зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to fx-team
This commit is contained in:
Коммит
d1e027ccae
|
@ -34,6 +34,7 @@ else
|
|||
configure_dir = $(topsrcdir)
|
||||
endif
|
||||
|
||||
ifndef TEST_MOZBUILD
|
||||
ifndef MOZ_PROFILE_USE
|
||||
# We need to explicitly put backend.RecursiveMakeBackend here
|
||||
# otherwise the rule in rules.mk doesn't run early enough.
|
||||
|
@ -44,6 +45,7 @@ $(TIERS) binaries:: $(topsrcdir)/js/src/configure js/src/config.status
|
|||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef JS_STANDALONE
|
||||
.PHONY: CLOBBER
|
||||
|
@ -81,6 +83,7 @@ config.status js/src/config.status:
|
|||
# The mach build driver will ensure the backend is up to date for partial tree
|
||||
# builds. This cleanly avoids most of the pain.
|
||||
|
||||
ifndef TEST_MOZBUILD
|
||||
backend.RecursiveMakeBackend:
|
||||
@echo 'Build configuration changed. Regenerating backend.'
|
||||
$(PYTHON) config.status
|
||||
|
@ -91,6 +94,7 @@ Makefile: backend.RecursiveMakeBackend
|
|||
include backend.RecursiveMakeBackend.pp
|
||||
|
||||
default:: backend.RecursiveMakeBackend
|
||||
endif
|
||||
|
||||
install_manifests := \
|
||||
$(addprefix dist/,bin branding idl include public private sdk xpi-stage) \
|
||||
|
|
|
@ -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->IsDefunct())
|
||||
mAccessibleCache.Enumerate(UnbindCacheEntryFromDocument<Accessible>, nullptr);
|
||||
if (!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->IsDefunct()) {
|
||||
mAccessibleCache.Enumerate(UnbindCacheEntryFromDocument<XULTreeGridCellAccessible>,
|
||||
nullptr);
|
||||
UnbindCacheEntriesFromDocument(mAccessibleCache);
|
||||
}
|
||||
|
||||
XULTreeItemAccessibleBase::Shutdown();
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
# 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/.
|
||||
|
||||
# Makefile.in uses a misc target through test_addons_TARGET.
|
||||
HAS_MISC_RULE = True
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
|
||||
JETPACK_PACKAGE_MANIFESTS += ['source/test/jetpack-package.ini']
|
||||
JETPACK_ADDON_MANIFESTS += ['source/test/addons/jetpack-addon.ini']
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
# 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/.
|
||||
|
||||
# Makefile.in uses a misc target through test_addons_TARGET.
|
||||
HAS_MISC_RULE = True
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ['test/browser.ini']
|
||||
JETPACK_PACKAGE_MANIFESTS += ['source/test/jetpack-package.ini']
|
||||
JETPACK_ADDON_MANIFESTS += ['source/test/addons/jetpack-addon.ini']
|
||||
|
|
|
@ -74,10 +74,10 @@ if CONFIG['OS_ARCH'] == 'WINNT':
|
|||
if CONFIG['GNU_CXX']:
|
||||
CXXFLAGS += ['-Wshadow']
|
||||
|
||||
JS_PREFERENCE_FILES += [
|
||||
JS_PREFERENCE_PP_FILES += [
|
||||
'b2g.js',
|
||||
]
|
||||
|
||||
DIST_FILES += [
|
||||
FINAL_TARGET_PP_FILES += [
|
||||
'ua-update.json.in',
|
||||
]
|
||||
|
|
|
@ -8,4 +8,4 @@
|
|||
% locale branding @AB_CD@ %locale/branding/
|
||||
# Branding only exists in en-US
|
||||
locale/branding/brand.dtd (en-US/brand.dtd)
|
||||
* locale/branding/brand.properties (en-US/brand.properties)
|
||||
locale/branding/brand.properties (en-US/brand.properties)
|
||||
|
|
|
@ -8,4 +8,4 @@
|
|||
% locale branding @AB_CD@ %locale/branding/
|
||||
# Branding only exists in en-US
|
||||
locale/branding/brand.dtd (en-US/brand.dtd)
|
||||
* locale/branding/brand.properties (en-US/brand.properties)
|
||||
locale/branding/brand.properties (en-US/brand.properties)
|
||||
|
|
|
@ -8,4 +8,4 @@
|
|||
% locale branding @AB_CD@ %locale/branding/
|
||||
# Nightly branding only exists in en-US
|
||||
locale/branding/brand.dtd (en-US/brand.dtd)
|
||||
* locale/branding/brand.properties (en-US/brand.properties)
|
||||
locale/branding/brand.properties (en-US/brand.properties)
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="538c96ab7f17adbbd15b82f750e7247c5685e831"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="59c8605876736b22acaaed25be00008e452149cb"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="538c96ab7f17adbbd15b82f750e7247c5685e831"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="59c8605876736b22acaaed25be00008e452149cb"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
|
||||
<default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
|
||||
<!-- Gecko and Gaia -->
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="538c96ab7f17adbbd15b82f750e7247c5685e831"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="59c8605876736b22acaaed25be00008e452149cb"/>
|
||||
<!-- Gonk-specific things and forks -->
|
||||
<project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
|
||||
<project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
</project>
|
||||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="538c96ab7f17adbbd15b82f750e7247c5685e831"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="59c8605876736b22acaaed25be00008e452149cb"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ac7e9ae8a24ab4a3f3da801ca53f95f39a32b89f"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5de6856fad82857028f9f059f50680a9bea5b75c"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="538c96ab7f17adbbd15b82f750e7247c5685e831"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="59c8605876736b22acaaed25be00008e452149cb"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="538c96ab7f17adbbd15b82f750e7247c5685e831"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="59c8605876736b22acaaed25be00008e452149cb"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
<project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
|
||||
<default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
|
||||
<!-- Gecko and Gaia -->
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="538c96ab7f17adbbd15b82f750e7247c5685e831"/>
|
||||
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="59c8605876736b22acaaed25be00008e452149cb"/>
|
||||
<!-- Gonk-specific things and forks -->
|
||||
<project name="platform_bionic" path="bionic" remote="b2g" revision="e2b3733ba3fa5e3f404e983d2e4142b1f6b1b846"/>
|
||||
<project name="platform_build" path="build" remote="b2g" revision="1b0db93fb6b870b03467aff50d6419771ba0d88c">
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="538c96ab7f17adbbd15b82f750e7247c5685e831"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="59c8605876736b22acaaed25be00008e452149cb"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{
|
||||
"git": {
|
||||
"git_revision": "538c96ab7f17adbbd15b82f750e7247c5685e831",
|
||||
"git_revision": "59c8605876736b22acaaed25be00008e452149cb",
|
||||
"remote": "https://git.mozilla.org/releases/gaia.git",
|
||||
"branch": ""
|
||||
},
|
||||
"revision": "183b45c6d96733ce09aee5eb7d7882b0d81f020d",
|
||||
"revision": "09d11f2ffa29c5f32712084fb8ac6023056f6c24",
|
||||
"repo_path": "integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="8d83715f08b7849f16a0dfc88f78d5c3a89c0a54">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="538c96ab7f17adbbd15b82f750e7247c5685e831"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="59c8605876736b22acaaed25be00008e452149cb"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="538c96ab7f17adbbd15b82f750e7247c5685e831"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="59c8605876736b22acaaed25be00008e452149cb"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
<project name="moztt" path="external/moztt" remote="b2g" revision="ac7e9ae8a24ab4a3f3da801ca53f95f39a32b89f"/>
|
||||
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="5de6856fad82857028f9f059f50680a9bea5b75c"/>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<project name="platform_build" path="build" remote="b2g" revision="c9d4fe680662ee44a4bdea42ae00366f5df399cf">
|
||||
<copyfile dest="Makefile" src="core/root.mk"/>
|
||||
</project>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="538c96ab7f17adbbd15b82f750e7247c5685e831"/>
|
||||
<project name="gaia" path="gaia" remote="mozillaorg" revision="59c8605876736b22acaaed25be00008e452149cb"/>
|
||||
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
|
||||
<project name="fake-qemu-kernel" path="prebuilts/qemu-kernel" remote="b2g" revision="939b377d55a2f081d94029a30a75d05e5a20daf3"/>
|
||||
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="4a962bdab532e18f53e9d2d114c349983262c6b7"/>
|
||||
|
|
|
@ -5,8 +5,11 @@
|
|||
DIST_SUBDIR = 'browser'
|
||||
export('DIST_SUBDIR')
|
||||
|
||||
JS_PREFERENCE_FILES += [
|
||||
'/b2g/app/b2g.js',
|
||||
'/b2g/dev/app/mulet.js',
|
||||
JS_PREFERENCE_PP_FILES += [
|
||||
'../../app/b2g.js',
|
||||
]
|
||||
|
||||
JS_PREFERENCE_FILES += [
|
||||
'mulet.js',
|
||||
]
|
||||
|
||||
|
|
|
@ -15,6 +15,13 @@
|
|||
"unpack": true
|
||||
},
|
||||
{
|
||||
"size": 73029932,
|
||||
"digest": "ef1818acf065838dcb72554e521f9fd7098f0a3690cb6a3106d7bf18f46c342bfdd5a2b7d86e92ee3ddb9e478380343e58ecf8fd242807b8881a2d53fbec5ab3",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.xz",
|
||||
"unpack": true
|
||||
},
|
||||
{
|
||||
"size": 167175,
|
||||
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
|
||||
"algorithm": "sha512",
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
% override chrome://global/locale/aboutCertError.dtd chrome://b2g-l10n/locale/aboutCertError.dtd
|
||||
% override chrome://global/locale/appstrings.properties chrome://b2g-l10n/locale/appstrings.properties
|
||||
* locale/@AB_CD@/b2g-l10n/aboutCertError.dtd (%chrome/overrides/aboutCertError.dtd)
|
||||
* locale/@AB_CD@/b2g-l10n/appstrings.properties (%chrome/overrides/appstrings.properties)
|
||||
locale/@AB_CD@/b2g-l10n/aboutCertError.dtd (%chrome/overrides/aboutCertError.dtd)
|
||||
locale/@AB_CD@/b2g-l10n/appstrings.properties (%chrome/overrides/appstrings.properties)
|
||||
#ifdef MOZ_GRAPHENE
|
||||
locale/@AB_CD@/b2g-l10n/graphene.properties (%chrome/graphene.properties)
|
||||
#endif
|
||||
|
|
|
@ -11,7 +11,7 @@ if CONFIG['OS_ARCH'] == 'WINNT' and CONFIG['MOZ_ASAN']:
|
|||
else:
|
||||
GeckoProgram(CONFIG['MOZ_APP_NAME'], msvcrt='static')
|
||||
|
||||
JS_PREFERENCE_FILES += [
|
||||
JS_PREFERENCE_PP_FILES += [
|
||||
'profile/firefox.js',
|
||||
]
|
||||
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
|
||||
FINAL_TARGET = 'dist/bin/browser/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}'
|
||||
|
||||
DIST_FILES += [
|
||||
FINAL_TARGET_PP_FILES += [
|
||||
'install.rdf.in',
|
||||
]
|
||||
|
|
|
@ -1608,17 +1608,13 @@ pref("browser.pocket.enabledLocales", "cs de en-GB en-US en-ZA es-ES es-MX fr hu
|
|||
|
||||
pref("view_source.tab", true);
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
// Enable ServiceWorkers for Push API consumers.
|
||||
// Interception is still disabled on beta and release.
|
||||
pref("dom.serviceWorkers.enabled", true);
|
||||
|
||||
pref("dom.serviceWorkers.interception.enabled", true);
|
||||
pref("dom.serviceWorkers.openWindow.enabled", true);
|
||||
|
||||
#ifndef RELEASE_BUILD
|
||||
// Enable Push API.
|
||||
pref("dom.push.enabled", true);
|
||||
|
||||
pref("dom.serviceWorkers.openWindow.enabled", true);
|
||||
#endif
|
||||
|
||||
// These are the thumbnail width/height set in about:newtab.
|
||||
|
|
|
@ -1346,8 +1346,7 @@ nsContextMenu.prototype = {
|
|||
// checks after redirects, see bug: 1136055
|
||||
var channel = NetUtil.newChannel({
|
||||
uri: makeURI(linkURL),
|
||||
loadUsingSystemPrincipal: true,
|
||||
securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL
|
||||
loadUsingSystemPrincipal: true
|
||||
});
|
||||
|
||||
if (linkDownload)
|
||||
|
|
|
@ -273,7 +273,7 @@ var RemoteTabViewer = {
|
|||
}.bind(this);
|
||||
|
||||
return CloudSync().tabs.getRemoteTabs()
|
||||
.then(updateTabList, Promise.reject);
|
||||
.then(updateTabList, Promise.reject.bind(Promise));
|
||||
},
|
||||
|
||||
adjustContextMenu: function (event) {
|
||||
|
|
|
@ -7,5 +7,5 @@
|
|||
@AB_CD@.jar:
|
||||
% locale branding @AB_CD@ %locale/branding/
|
||||
locale/branding/brand.dtd (%brand.dtd)
|
||||
* locale/branding/brand.properties (%brand.properties)
|
||||
* locale/branding/browserconfig.properties
|
||||
locale/branding/brand.properties (%brand.properties)
|
||||
locale/branding/browserconfig.properties
|
||||
|
|
|
@ -788,8 +788,8 @@ nsDefaultCommandLineHandler.prototype = {
|
|||
// * Cortana voice searches use "FORM=WNSBOX" or direct results, or "FORM=WNSFC2"
|
||||
// for "see more results on Bing.com")
|
||||
// * Cortana voice searches started from "Hey, Cortana" use "form=WNSHCO"
|
||||
// or "form=WNSSSV"
|
||||
var allowedParams = ["WNSGPH", "WNSBOX", "WNSFC2", "WNSHCO", "WNSSSV"];
|
||||
// or "form=WNSSSV" or "form=WNSSCX"
|
||||
var allowedParams = ["WNSGPH", "WNSBOX", "WNSFC2", "WNSHCO", "WNSSCX", "WNSSSV"];
|
||||
var formParam = params.get("form");
|
||||
if (!formParam) {
|
||||
formParam = params.get("FORM");
|
||||
|
|
|
@ -18,5 +18,6 @@ export MOZ_PACKAGE_JSSHELL=1
|
|||
|
||||
ac_add_options --with-branding=browser/branding/nightly
|
||||
|
||||
. "$topsrcdir/build/unix/mozconfig.rust"
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
. "$topsrcdir/build/mozconfig.cache"
|
||||
|
|
|
@ -10,5 +10,6 @@ STRIP_FLAGS="--strip-debug"
|
|||
|
||||
ac_add_options --with-branding=browser/branding/nightly
|
||||
|
||||
. "$topsrcdir/build/unix/mozconfig.rust"
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
. "$topsrcdir/build/mozconfig.cache"
|
||||
|
|
|
@ -40,6 +40,7 @@ whitelist['nightly']['linux64'] += [
|
|||
'STRIP_FLAGS="--strip-debug"',
|
||||
'ac_add_options --with-ccache=/usr/bin/ccache',
|
||||
'. "$topsrcdir/build/mozconfig.cache"',
|
||||
'. "$topsrcdir/build/unix/mozconfig.rust"',
|
||||
]
|
||||
|
||||
whitelist['nightly']['macosx-universal'] += [
|
||||
|
|
|
@ -19,5 +19,12 @@
|
|||
"algorithm": "sha512",
|
||||
"filename": "sccache.tar.bz2",
|
||||
"unpack": true
|
||||
},
|
||||
{
|
||||
"size": 73029932,
|
||||
"digest": "ef1818acf065838dcb72554e521f9fd7098f0a3690cb6a3106d7bf18f46c342bfdd5a2b7d86e92ee3ddb9e478380343e58ecf8fd242807b8881a2d53fbec5ab3",
|
||||
"algorithm": "sha512",
|
||||
"filename": "rustc.tar.xz",
|
||||
"unpack": true
|
||||
}
|
||||
]
|
||||
|
|
|
@ -10,7 +10,7 @@ FINAL_TARGET_FILES += [
|
|||
'bootstrap.js'
|
||||
]
|
||||
|
||||
DIST_FILES += [
|
||||
FINAL_TARGET_PP_FILES += [
|
||||
'install.rdf.in'
|
||||
]
|
||||
|
||||
|
|
|
@ -73,6 +73,6 @@ if CONFIG['MOZ_ASAN'] and CONFIG['CLANG_CL']:
|
|||
FINAL_TARGET_FILES += [CONFIG['MOZ_CLANG_RT_ASAN_LIB_PATH']]
|
||||
|
||||
if CONFIG['MOZ_APP_BASENAME']:
|
||||
DIST_FILES += ['application.ini']
|
||||
FINAL_TARGET_PP_FILES += ['application.ini']
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android' and CONFIG['MOZ_UPDATER']:
|
||||
DIST_FILES += ['update-settings.ini']
|
||||
FINAL_TARGET_PP_FILES += ['update-settings.ini']
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# Options to enable rust in automation builds.
|
||||
|
||||
# Tell configure to use the tooltool rustc.
|
||||
# Assume this is compiled with --enable-rpath so we don't
|
||||
# have to set LD_LIBRARY_PATH.
|
||||
RUSTC="$topsrcdir/rustc/bin/rustc"
|
||||
|
||||
# Enable rust in the build.
|
||||
ac_add_options --enable-rust
|
|
@ -6,17 +6,10 @@ includedir := $(includedir)/$(MOZ_APP_NAME)-$(MOZ_APP_VERSION)
|
|||
idldir = $(datadir)/idl/$(MOZ_APP_NAME)-$(MOZ_APP_VERSION)
|
||||
installdir = $(libdir)/$(MOZ_APP_NAME)-$(MOZ_APP_VERSION)
|
||||
sdkdir = $(libdir)/$(MOZ_APP_NAME)-devel-$(MOZ_APP_VERSION)
|
||||
ifndef TOP_DIST
|
||||
TOP_DIST = dist
|
||||
endif
|
||||
ifneq (,$(filter /%,$(TOP_DIST)))
|
||||
DIST = $(TOP_DIST)
|
||||
else
|
||||
ifeq (.,$(DEPTH))
|
||||
DIST = $(TOP_DIST)
|
||||
DIST = dist
|
||||
else
|
||||
DIST = $(DEPTH)/$(TOP_DIST)
|
||||
endif
|
||||
DIST = $(DEPTH)/dist
|
||||
endif
|
||||
|
||||
# We do magic with OBJ_SUFFIX in config.mk, the following ensures we don't
|
||||
|
|
|
@ -43,13 +43,20 @@ default: $(addprefix install-,$(INSTALL_MANIFESTS))
|
|||
|
||||
# Explicit files to be built for a default build
|
||||
default: $(addprefix $(TOPOBJDIR)/,$(MANIFEST_TARGETS))
|
||||
ifndef TEST_MOZBUILD
|
||||
default: $(TOPOBJDIR)/dist/bin/platform.ini
|
||||
endif
|
||||
|
||||
ifndef NO_XPIDL
|
||||
# Targets from the recursive make backend to be built for a default build
|
||||
default: $(TOPOBJDIR)/config/makefiles/xpidl/xpidl
|
||||
endif
|
||||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
# Mac builds require to copy things in dist/bin/*.app
|
||||
# TODO: remove the MOZ_WIDGET_TOOLKIT and MOZ_BUILD_APP variables from
|
||||
# faster/Makefile and python/mozbuild/mozbuild/test/backend/test_build.py
|
||||
# when this is not required anymore.
|
||||
default:
|
||||
$(MAKE) -C $(TOPOBJDIR)/$(MOZ_BUILD_APP)/app repackage
|
||||
endif
|
||||
|
@ -77,6 +84,7 @@ $(TOPOBJDIR)/_virtualenv/%: ;
|
|||
# if there is no other rule.
|
||||
$(TOPOBJDIR)/dist/%:
|
||||
rm -f $@
|
||||
mkdir -p $(@D)
|
||||
cp $< $@
|
||||
|
||||
# Refresh backend
|
||||
|
|
|
@ -5,19 +5,6 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
ifndef NO_DIST_INSTALL
|
||||
ifdef SHARED_LIBRARY
|
||||
ifdef IS_COMPONENT
|
||||
target:: $(SUBMAKEFILES) $(SHARED_LIBRARY)
|
||||
$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)/components
|
||||
ifndef NO_COMPONENTS_MANIFEST
|
||||
$(call py_action,buildlist,$(FINAL_TARGET)/chrome.manifest 'manifest components/components.manifest')
|
||||
$(call py_action,buildlist,$(FINAL_TARGET)/components/components.manifest 'binary-component $(SHARED_LIBRARY)')
|
||||
endif
|
||||
endif # IS_COMPONENT
|
||||
endif # SHARED_LIBRARY
|
||||
endif # !NO_DIST_INSTALL
|
||||
|
||||
ifndef NO_DIST_INSTALL
|
||||
|
||||
ifneq (,$(strip $(PROGRAM)$(SIMPLE_PROGRAMS)))
|
||||
|
@ -37,12 +24,10 @@ endif # LIBRARY
|
|||
|
||||
|
||||
ifdef SHARED_LIBRARY
|
||||
ifndef IS_COMPONENT
|
||||
SHARED_LIBRARY_FILES = $(SHARED_LIBRARY)
|
||||
SHARED_LIBRARY_DEST ?= $(FINAL_TARGET)
|
||||
SHARED_LIBRARY_DEST ?= $(FINAL_TARGET)$(if $(IS_COMPONENT),/components)
|
||||
SHARED_LIBRARY_TARGET = target
|
||||
INSTALL_TARGETS += SHARED_LIBRARY
|
||||
endif # ! IS_COMPONENT
|
||||
endif # SHARED_LIBRARY
|
||||
|
||||
ifneq (,$(strip $(HOST_SIMPLE_PROGRAMS)$(HOST_PROGRAM)))
|
||||
|
|
|
@ -1138,9 +1138,8 @@ export:: $(FINAL_TARGET)
|
|||
endif
|
||||
|
||||
################################################################################
|
||||
# Copy each element of PREF_JS_EXPORTS
|
||||
|
||||
# The default location for PREF_JS_EXPORTS is the gre prefs directory.
|
||||
# The default location for prefs is the gre prefs directory.
|
||||
# PREF_DIR is used for L10N_PREF_JS_EXPORTS in various locales/ directories.
|
||||
PREF_DIR = defaults/pref
|
||||
|
||||
# If DIST_SUBDIR is defined it indicates that app and gre dirs are
|
||||
|
@ -1150,16 +1149,6 @@ ifneq (,$(DIST_SUBDIR)$(XPI_NAME))
|
|||
PREF_DIR = defaults/preferences
|
||||
endif
|
||||
|
||||
ifneq ($(PREF_JS_EXPORTS),)
|
||||
ifndef NO_DIST_INSTALL
|
||||
PREF_JS_EXPORTS_PATH := $(FINAL_TARGET)/$(PREF_DIR)
|
||||
# We preprocess these, but they don't necessarily have preprocessor directives,
|
||||
# so tell them preprocessor to not complain about that.
|
||||
PREF_JS_EXPORTS_FLAGS := $(PREF_PPFLAGS) --silence-missing-directive-warnings
|
||||
PP_TARGETS += PREF_JS_EXPORTS
|
||||
endif
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# Copy each element of AUTOCFG_JS_EXPORTS to $(FINAL_TARGET)/defaults/autoconfig
|
||||
|
||||
|
@ -1172,33 +1161,6 @@ INSTALL_TARGETS += AUTOCFG_JS_EXPORTS
|
|||
endif
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# Copy each element of EXTRA_COMPONENTS to $(FINAL_TARGET)/components
|
||||
ifdef EXTRA_COMPONENTS
|
||||
misc:: $(EXTRA_COMPONENTS)
|
||||
ifndef NO_DIST_INSTALL
|
||||
EXTRA_COMPONENTS_FILES := $(EXTRA_COMPONENTS)
|
||||
EXTRA_COMPONENTS_DEST := $(FINAL_TARGET)/components
|
||||
EXTRA_COMPONENTS_TARGET := misc
|
||||
INSTALL_TARGETS += EXTRA_COMPONENTS
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
ifdef EXTRA_PP_COMPONENTS
|
||||
ifndef NO_DIST_INSTALL
|
||||
EXTRA_PP_COMPONENTS_PATH := $(FINAL_TARGET)/components
|
||||
EXTRA_PP_COMPONENTS_TARGET := misc
|
||||
PP_TARGETS += EXTRA_PP_COMPONENTS
|
||||
endif
|
||||
endif
|
||||
|
||||
EXTRA_MANIFESTS = $(filter %.manifest,$(EXTRA_COMPONENTS) $(EXTRA_PP_COMPONENTS))
|
||||
ifneq (,$(EXTRA_MANIFESTS))
|
||||
misc:: $(call mkdir_deps,$(FINAL_TARGET))
|
||||
$(call py_action,buildlist,$(FINAL_TARGET)/chrome.manifest $(patsubst %,'manifest components/%',$(notdir $(EXTRA_MANIFESTS))))
|
||||
endif
|
||||
|
||||
################################################################################
|
||||
# SDK
|
||||
|
||||
|
@ -1268,14 +1230,6 @@ $(error $(srcdir) contains a jar.mn file but this file is not declared in a JAR_
|
|||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(DIST_FILES),)
|
||||
DIST_FILES_PATH := $(FINAL_TARGET)
|
||||
# We preprocess these, but they don't necessarily have preprocessor directives,
|
||||
# so tell them preprocessor to not complain about that.
|
||||
DIST_FILES_FLAGS := --silence-missing-directive-warnings
|
||||
PP_TARGETS += DIST_FILES
|
||||
endif
|
||||
|
||||
# When you move this out of the tools tier, please remove the corresponding
|
||||
# hacks in recursivemake.py that check if Makefile.in sets the variable.
|
||||
ifneq ($(XPI_PKGNAME),)
|
||||
|
@ -1592,8 +1546,6 @@ FREEZE_VARIABLES = \
|
|||
DIRS \
|
||||
LIBRARY \
|
||||
MODULE \
|
||||
EXTRA_COMPONENTS \
|
||||
EXTRA_PP_COMPONENTS \
|
||||
$(NULL)
|
||||
|
||||
$(foreach var,$(FREEZE_VARIABLES),$(eval $(var)_FROZEN := '$($(var))'))
|
||||
|
|
|
@ -1328,6 +1328,7 @@ xlocale.h
|
|||
#ifdef MOZ_SHARED_ICU
|
||||
unicode/locid.h
|
||||
unicode/numsys.h
|
||||
unicode/timezone.h
|
||||
unicode/ucal.h
|
||||
unicode/uchar.h
|
||||
unicode/uclean.h
|
||||
|
|
15
configure.in
15
configure.in
|
@ -672,7 +672,7 @@ See https://developer.mozilla.org/en/Windows_Build_Prerequisites.])
|
|||
fi
|
||||
|
||||
if test "$WRAP_STL_INCLUDES" = "1"; then
|
||||
STL_FLAGS='-I$(DIST)/stl_wrappers'
|
||||
STL_FLAGS="-I${DIST}/stl_wrappers"
|
||||
fi
|
||||
CFLAGS="$CFLAGS -D_HAS_EXCEPTIONS=0"
|
||||
CXXFLAGS="$CXXFLAGS -D_HAS_EXCEPTIONS=0"
|
||||
|
@ -2583,7 +2583,7 @@ if test "$GNU_CC" -a "$OS_TARGET" != WINNT; then
|
|||
VISIBILITY_FLAGS='-fvisibility=hidden -fvisibility-inlines-hidden'
|
||||
;;
|
||||
*)
|
||||
VISIBILITY_FLAGS='-I$(DIST)/system_wrappers -include $(MOZILLA_DIR)/config/gcc_hidden.h'
|
||||
VISIBILITY_FLAGS="-I${DIST}/system_wrappers -include ${_topsrcdir}/config/gcc_hidden.h"
|
||||
WRAP_SYSTEM_INCLUDES=1
|
||||
;;
|
||||
esac
|
||||
|
@ -2598,13 +2598,13 @@ case "${OS_TARGET}" in
|
|||
WINNT|Darwin|Android)
|
||||
;;
|
||||
*)
|
||||
STL_FLAGS='-I$(DIST)/stl_wrappers'
|
||||
STL_FLAGS="-I${DIST}/stl_wrappers"
|
||||
WRAP_STL_INCLUDES=1
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(WRAP_SYSTEM_INCLUDES)
|
||||
AC_SUBST(VISIBILITY_FLAGS)
|
||||
AC_SUBST_LIST(VISIBILITY_FLAGS)
|
||||
|
||||
dnl Checks for header files.
|
||||
dnl ========================================================
|
||||
|
@ -8143,12 +8143,8 @@ fi
|
|||
if test "$MOZ_TREE_PIXMAN"; then
|
||||
AC_DEFINE(MOZ_TREE_PIXMAN)
|
||||
else
|
||||
PKG_CHECK_MODULES(PIXMAN, pixman-1 >= 0.19.2)
|
||||
MOZ_PIXMAN_CFLAGS="$PIXMAN_CFLAGS"
|
||||
MOZ_PIXMAN_LIBS="$PIXMAN_LIBS"
|
||||
PKG_CHECK_MODULES(MOZ_PIXMAN, pixman-1 >= 0.19.2)
|
||||
fi
|
||||
AC_SUBST(MOZ_PIXMAN_CFLAGS)
|
||||
AC_SUBST_LIST(MOZ_PIXMAN_LIBS)
|
||||
|
||||
# Check for headers defining standard int types.
|
||||
if test -n "$COMPILE_ENVIRONMENT"; then
|
||||
|
@ -9275,6 +9271,7 @@ export MOZILLA_CENTRAL_PATH=$_topsrcdir
|
|||
export STLPORT_CPPFLAGS
|
||||
export STLPORT_LIBS
|
||||
export JS_STANDALONE=no
|
||||
export DIST
|
||||
export MOZ_LINKER
|
||||
export ZLIB_IN_MOZGLUE
|
||||
export MOZ_MEMORY
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
JS_PREFERENCE_FILES += [
|
||||
JS_PREFERENCE_PP_FILES += [
|
||||
'devtools.js',
|
||||
]
|
||||
|
|
|
@ -192,6 +192,7 @@ skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
|||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_eval_in_debugger_stackframe2.js]
|
||||
[browser_jsterm_inspect.js]
|
||||
skip-if = e10s && debug && os == 'win'
|
||||
[browser_longstring_hang.js]
|
||||
[browser_output_breaks_after_console_dir_uninspectable.js]
|
||||
[browser_output_longstring_expand.js]
|
||||
|
|
|
@ -18,6 +18,6 @@ MOCHITEST_CHROME_MANIFESTS += [
|
|||
'test/chrome.ini'
|
||||
]
|
||||
|
||||
JS_PREFERENCE_FILES += [
|
||||
JS_PREFERENCE_PP_FILES += [
|
||||
'webide-prefs.js',
|
||||
]
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/devtools/DominatorTree.h"
|
||||
|
||||
#include "js/Debug.h"
|
||||
#include "mozilla/CycleCollectedJSRuntime.h"
|
||||
#include "mozilla/dom/DominatorTreeBinding.h"
|
||||
|
@ -12,6 +11,18 @@
|
|||
namespace mozilla {
|
||||
namespace devtools {
|
||||
|
||||
static MallocSizeOf
|
||||
getCurrentThreadDebuggerMallocSizeOf()
|
||||
{
|
||||
auto ccrt = CycleCollectedJSRuntime::Get();
|
||||
MOZ_ASSERT(ccrt);
|
||||
auto rt = ccrt->Runtime();
|
||||
MOZ_ASSERT(rt);
|
||||
auto mallocSizeOf = JS::dbg::GetDebuggerMallocSizeOf(rt);
|
||||
MOZ_ASSERT(mallocSizeOf);
|
||||
return mallocSizeOf;
|
||||
}
|
||||
|
||||
dom::Nullable<uint64_t>
|
||||
DominatorTree::GetRetainedSize(uint64_t aNodeId, ErrorResult& aRv)
|
||||
{
|
||||
|
@ -20,13 +31,7 @@ DominatorTree::GetRetainedSize(uint64_t aNodeId, ErrorResult& aRv)
|
|||
if (node.isNothing())
|
||||
return dom::Nullable<uint64_t>();
|
||||
|
||||
auto ccrt = CycleCollectedJSRuntime::Get();
|
||||
MOZ_ASSERT(ccrt);
|
||||
auto rt = ccrt->Runtime();
|
||||
MOZ_ASSERT(rt);
|
||||
auto mallocSizeOf = JS::dbg::GetDebuggerMallocSizeOf(rt);
|
||||
MOZ_ASSERT(mallocSizeOf);
|
||||
|
||||
auto mallocSizeOf = getCurrentThreadDebuggerMallocSizeOf();
|
||||
JS::ubi::Node::Size size = 0;
|
||||
if (!mDominatorTree.getRetainedSize(*node, mallocSizeOf, size)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
|
@ -38,6 +43,94 @@ DominatorTree::GetRetainedSize(uint64_t aNodeId, ErrorResult& aRv)
|
|||
return dom::Nullable<uint64_t>(size);
|
||||
}
|
||||
|
||||
struct NodeAndRetainedSize
|
||||
{
|
||||
JS::ubi::Node mNode;
|
||||
JS::ubi::Node::Size mSize;
|
||||
|
||||
NodeAndRetainedSize(const JS::ubi::Node& aNode, JS::ubi::Node::Size aSize)
|
||||
: mNode(aNode)
|
||||
, mSize(aSize)
|
||||
{ }
|
||||
|
||||
struct Comparator
|
||||
{
|
||||
static bool
|
||||
Equals(const NodeAndRetainedSize& aLhs, const NodeAndRetainedSize& aRhs)
|
||||
{
|
||||
return aLhs.mSize == aRhs.mSize;
|
||||
}
|
||||
|
||||
static bool
|
||||
LessThan(const NodeAndRetainedSize& aLhs, const NodeAndRetainedSize& aRhs)
|
||||
{
|
||||
// Use > because we want to sort from greatest to least retained size.
|
||||
return aLhs.mSize > aRhs.mSize;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void
|
||||
DominatorTree::GetImmediatelyDominated(uint64_t aNodeId,
|
||||
dom::Nullable<nsTArray<uint64_t>>& aOutResult,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aOutResult.IsNull());
|
||||
|
||||
JS::ubi::Node::Id id(aNodeId);
|
||||
Maybe<JS::ubi::Node> node = mHeapSnapshot->getNodeById(id);
|
||||
if (node.isNothing())
|
||||
return;
|
||||
|
||||
// Get all immediately dominated nodes and their retained sizes.
|
||||
MallocSizeOf mallocSizeOf = getCurrentThreadDebuggerMallocSizeOf();
|
||||
Maybe<JS::ubi::DominatorTree::DominatedSetRange> range = mDominatorTree.getDominatedSet(*node);
|
||||
MOZ_ASSERT(range.isSome(), "The node should be known, since we got it from the heap snapshot.");
|
||||
size_t length = range->length();
|
||||
nsTArray<NodeAndRetainedSize> dominatedNodes(length);
|
||||
for (const JS::ubi::Node& dominatedNode : *range) {
|
||||
JS::ubi::Node::Size retainedSize = 0;
|
||||
if (NS_WARN_IF(!mDominatorTree.getRetainedSize(dominatedNode, mallocSizeOf, retainedSize))) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(retainedSize != 0,
|
||||
"retainedSize should not be zero since we know the node is in the dominator tree.");
|
||||
|
||||
dominatedNodes.AppendElement(NodeAndRetainedSize(dominatedNode, retainedSize));
|
||||
}
|
||||
|
||||
// Sort them by retained size.
|
||||
NodeAndRetainedSize::Comparator comparator;
|
||||
dominatedNodes.Sort(comparator);
|
||||
|
||||
// Fill the result with the nodes' ids.
|
||||
JS::ubi::Node root = mDominatorTree.root();
|
||||
aOutResult.SetValue(nsTArray<uint64_t>(length));
|
||||
for (const NodeAndRetainedSize& entry : dominatedNodes) {
|
||||
// The root dominates itself, but we don't want to expose that to JS.
|
||||
if (entry.mNode == root)
|
||||
continue;
|
||||
|
||||
aOutResult.Value().AppendElement(entry.mNode.identifier());
|
||||
}
|
||||
}
|
||||
|
||||
dom::Nullable<uint64_t>
|
||||
DominatorTree::GetImmediateDominator(uint64_t aNodeId) const
|
||||
{
|
||||
JS::ubi::Node::Id id(aNodeId);
|
||||
Maybe<JS::ubi::Node> node = mHeapSnapshot->getNodeById(id);
|
||||
if (node.isNothing())
|
||||
return dom::Nullable<uint64_t>();
|
||||
|
||||
JS::ubi::Node dominator = mDominatorTree.getImmediateDominator(*node);
|
||||
if (!dominator || dominator == *node)
|
||||
return dom::Nullable<uint64_t>();
|
||||
|
||||
return dom::Nullable<uint64_t>(dominator.identifier());
|
||||
}
|
||||
|
||||
|
||||
/*** Cycle Collection Boilerplate *****************************************************************/
|
||||
|
||||
|
|
|
@ -52,6 +52,13 @@ public:
|
|||
|
||||
// [Throws] NodeSize getRetainedSize(NodeId node)
|
||||
dom::Nullable<uint64_t> GetRetainedSize(uint64_t aNodeId, ErrorResult& aRv);
|
||||
|
||||
// [Throws] sequence<NodeId>? getImmediatelyDominated(NodeId node);
|
||||
void GetImmediatelyDominated(uint64_t aNodeId, dom::Nullable<nsTArray<uint64_t>>& aOutDominated,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// NodeId? getImmediateDominator(NodeId node);
|
||||
dom::Nullable<uint64_t> GetImmediateDominator(uint64_t aNodeId) const;
|
||||
};
|
||||
|
||||
} // namespace devtools
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that we can get the set of immediately dominated nodes for any given
|
||||
// node and that this forms a tree.
|
||||
|
||||
function run_test() {
|
||||
var dominatorTree = saveHeapSnapshotAndComputeDominatorTree();
|
||||
equal(typeof dominatorTree.getImmediatelyDominated, "function",
|
||||
"getImmediatelyDominated should be a function");
|
||||
|
||||
// Do a traversal of the dominator tree.
|
||||
//
|
||||
// Note that we don't assert directly, only if we get an unexpected
|
||||
// value. There are just way too many nodes in the heap graph to assert for
|
||||
// every one. This test would constantly time out and assertion messages would
|
||||
// overflow the log size.
|
||||
|
||||
var root = dominatorTree.root;
|
||||
equal(dominatorTree.getImmediateDominator(root), null,
|
||||
"The root should not have a parent");
|
||||
|
||||
var seen = new Set();
|
||||
var stack = [root];
|
||||
while (stack.length > 0) {
|
||||
var top = stack.pop();
|
||||
|
||||
if (seen.has(top)) {
|
||||
ok(false,
|
||||
"This is a tree, not a graph: we shouldn't have multiple edges to the same node");
|
||||
}
|
||||
seen.add(top);
|
||||
if (seen.size % 1000 === 0) {
|
||||
dumpn("Progress update: seen size = " + seen.size);
|
||||
}
|
||||
|
||||
var newNodes = dominatorTree.getImmediatelyDominated(top);
|
||||
if (Object.prototype.toString.call(newNodes) !== "[object Array]") {
|
||||
ok(false, "getImmediatelyDominated should return an array for known node ids");
|
||||
}
|
||||
|
||||
var topSize = dominatorTree.getRetainedSize(top);
|
||||
|
||||
var lastSize = Infinity;
|
||||
for (var i = 0; i < newNodes.length; i++) {
|
||||
if (typeof newNodes[i] !== "number") {
|
||||
ok(false, "Every dominated id should be a number");
|
||||
}
|
||||
|
||||
if (dominatorTree.getImmediateDominator(newNodes[i]) !== top) {
|
||||
ok(false, "child's parent should be the expected parent");
|
||||
}
|
||||
|
||||
var thisSize = dominatorTree.getRetainedSize(newNodes[i]);
|
||||
|
||||
if (thisSize >= topSize) {
|
||||
ok(false, "the size of children in the dominator tree should always be less than that of their parent");
|
||||
}
|
||||
|
||||
if (thisSize > lastSize) {
|
||||
ok(false,
|
||||
"children should be sorted by greatest to least retained size, "
|
||||
+ "lastSize = " + lastSize + ", thisSize = " + thisSize);
|
||||
}
|
||||
|
||||
lastSize = thisSize;
|
||||
stack.push(newNodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
ok(true, "Successfully walked the tree");
|
||||
dumpn("Walked " + seen.size + " nodes");
|
||||
|
||||
do_test_finished();
|
||||
}
|
|
@ -32,6 +32,7 @@ support-files =
|
|||
[test_DominatorTree_02.js]
|
||||
[test_DominatorTree_03.js]
|
||||
[test_DominatorTree_04.js]
|
||||
[test_DominatorTree_05.js]
|
||||
[test_HeapAnalyses_getCreationTime_01.js]
|
||||
[test_HeapAnalyses_readHeapSnapshot_01.js]
|
||||
[test_HeapAnalyses_takeCensusDiff_01.js]
|
||||
|
|
|
@ -13486,7 +13486,7 @@ nsDocShell::OnLinkClickSync(nsIContent* aContent,
|
|||
// if per element referrer is enabled, the element referrer overrules
|
||||
// the document wide referrer
|
||||
if (IsElementAnchor(aContent)) {
|
||||
net::ReferrerPolicy refPolEnum = aContent->AsElement()->GetReferrerPolicy();
|
||||
net::ReferrerPolicy refPolEnum = aContent->AsElement()->GetReferrerPolicyAsEnum();
|
||||
if (refPolEnum != net::RP_Unset) {
|
||||
refererPolicy = refPolEnum;
|
||||
}
|
||||
|
|
|
@ -883,6 +883,14 @@ this.InterAppCommService = {
|
|||
if (DEBUG) {
|
||||
debug("Unregistering message port for " + manifestURL);
|
||||
}
|
||||
|
||||
let receiver = identity.isPublisher ? identity.pair.subscriber
|
||||
: identity.pair.publisher;
|
||||
receiver.target.sendAsyncMessage("InterAppMessagePort:OnClose",
|
||||
{ manifestURL: receiver.manifestURL,
|
||||
pageURL: receiver.pageURL,
|
||||
messagePortID: messagePortID });
|
||||
|
||||
delete this._messagePortPairs[messagePortID];
|
||||
},
|
||||
|
||||
|
@ -901,7 +909,7 @@ this.InterAppCommService = {
|
|||
messagePortIDs.push(messagePortID);
|
||||
// Send a shutdown message to the part of the pair that is still alive.
|
||||
let actor = pair.publisher.target === aTarget ? pair.subscriber
|
||||
: pair.publisher;
|
||||
: pair.publisher;
|
||||
actor.target.sendAsyncMessage("InterAppMessagePort:Shutdown",
|
||||
{ manifestURL: actor.manifestURL,
|
||||
pageURL: actor.pageURL,
|
||||
|
|
|
@ -30,7 +30,8 @@ XPCOMUtils.defineLazyServiceGetter(this, "appsService",
|
|||
"@mozilla.org/AppsService;1",
|
||||
"nsIAppsService");
|
||||
|
||||
const kMessages = ["InterAppMessagePort:OnMessage",
|
||||
const kMessages = ["InterAppMessagePort:OnClose",
|
||||
"InterAppMessagePort:OnMessage",
|
||||
"InterAppMessagePort:Shutdown"];
|
||||
|
||||
function InterAppMessagePort() {
|
||||
|
@ -66,6 +67,7 @@ InterAppMessagePort.prototype = {
|
|||
this._started = false;
|
||||
this._closed = false;
|
||||
this._messageQueue = [];
|
||||
this._deferredClose = false;
|
||||
},
|
||||
|
||||
// WebIDL implementation for constructor.
|
||||
|
@ -131,6 +133,10 @@ InterAppMessagePort.prototype = {
|
|||
let message = this._messageQueue.shift();
|
||||
this._dispatchMessage(message);
|
||||
}
|
||||
|
||||
if (this._deferredClose) {
|
||||
this._dispatchClose();
|
||||
}
|
||||
},
|
||||
|
||||
close: function() {
|
||||
|
@ -143,6 +149,7 @@ InterAppMessagePort.prototype = {
|
|||
}
|
||||
|
||||
this._closed = true;
|
||||
this._deferredClose = false;
|
||||
this._messageQueue.length = 0;
|
||||
|
||||
// When this method called on a local port that is entangled with another
|
||||
|
@ -152,6 +159,8 @@ InterAppMessagePort.prototype = {
|
|||
manifestURL: this._manifestURL });
|
||||
|
||||
this.removeMessageListeners(kMessages);
|
||||
|
||||
this._dispatchClose();
|
||||
},
|
||||
|
||||
get onmessage() {
|
||||
|
@ -176,6 +185,16 @@ InterAppMessagePort.prototype = {
|
|||
this.start();
|
||||
},
|
||||
|
||||
get onclose() {
|
||||
if (DEBUG) debug("Getting onclose handler.");
|
||||
return this.__DOM_IMPL__.getEventHandler("onclose");
|
||||
},
|
||||
|
||||
set onclose(aHandler) {
|
||||
if (DEBUG) debug("Setting onclose handler.");
|
||||
this.__DOM_IMPL__.setEventHandler("onclose", aHandler);
|
||||
},
|
||||
|
||||
_dispatchMessage: function _dispatchMessage(aMessage) {
|
||||
let wrappedMessage = Cu.cloneInto(aMessage, this._window);
|
||||
if (DEBUG) {
|
||||
|
@ -189,6 +208,15 @@ InterAppMessagePort.prototype = {
|
|||
this.__DOM_IMPL__.dispatchEvent(event);
|
||||
},
|
||||
|
||||
_dispatchClose() {
|
||||
if (DEBUG) debug("_dispatchClose");
|
||||
let event = new this._window.Event("close", {
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
});
|
||||
this.__DOM_IMPL__.dispatchEvent(event);
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
if (DEBUG) debug("receiveMessage: name: " + aMessage.name);
|
||||
|
||||
|
@ -217,11 +245,32 @@ InterAppMessagePort.prototype = {
|
|||
this._dispatchMessage(message.message);
|
||||
break;
|
||||
|
||||
case "InterAppMessagePort:OnClose":
|
||||
if (this._closed) {
|
||||
if (DEBUG) debug("close() has been called. Drop the message.");
|
||||
return;
|
||||
}
|
||||
|
||||
// It is possible that one side of the port posts messages and calls
|
||||
// close() before calling start() or setting the onmessage handler. In
|
||||
// that case we need to queue the messages and defer the onclose event
|
||||
// until the messages are delivered to the other side of the port.
|
||||
if (!this._started) {
|
||||
if (DEBUG) debug("Not yet called start(). Defer close notification.");
|
||||
this._deferredClose = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this._dispatchClose();
|
||||
break;
|
||||
|
||||
case "InterAppMessagePort:Shutdown":
|
||||
this.close();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (DEBUG) debug("Error! Shouldn't fall into this case.");
|
||||
dump("WARNING - Invalid InterAppMessagePort message type " +
|
||||
aMessage.name + "\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,10 @@ XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
|
|||
|
||||
MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
|
||||
|
||||
MOCHITEST_CHROME_MANIFESTS += ['tests/chrome.ini']
|
||||
MOCHITEST_CHROME_MANIFESTS += [
|
||||
'tests/b2g_chrome.ini',
|
||||
'tests/chrome.ini'
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'InterAppComm.h',
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
[DEFAULT]
|
||||
skip-if = buildapp != 'b2g'
|
||||
support-files =
|
||||
iac/*
|
||||
|
||||
[test_iac.html]
|
|
@ -13,5 +13,5 @@ skip-if = os != 'linux'
|
|||
[test_operator_app_install.js]
|
||||
[test_operator_app_install.xul]
|
||||
# bug 928262
|
||||
skip-if = os == "win"
|
||||
skip-if = os == 'win'
|
||||
[test_packaged_app_asmjs.html]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "Certified hosted app",
|
||||
"description": "An app that can't only be installed in dev mode.",
|
||||
"description": "An app that can only be installed in dev mode.",
|
||||
"launch_path": "/tests/dom/apps/tests/file_app.sjs?apptype=hosted",
|
||||
"type": "certified"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
subscriber.list and publisher.zip contain the lists of files that are part of each app.
|
||||
|
||||
To update the packages of both apps when changing one of those files listed on *.list, run makezips.sh.
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
|
||||
rm publisher/publisher.zip
|
||||
rm subscriber/subscriber.zip
|
||||
cd publisher
|
||||
zip publisher.zip `cat publisher.list`
|
||||
cd ../subscriber
|
||||
zip subscriber.zip `cat subscriber.list`
|
||||
cd ..
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Publisher app for IAC API</title>
|
||||
<script src="test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"name": "IAC publisher app",
|
||||
"launch_path": "/index.html",
|
||||
"type": "certified"
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
manifest.webapp
|
||||
index.html
|
||||
test.js
|
Двоичный файл не отображается.
|
@ -0,0 +1,46 @@
|
|||
function ok(aCondition, aMessage) {
|
||||
if (aCondition) {
|
||||
alert("OK: " + aMessage);
|
||||
} else {
|
||||
alert("KO: " + aMessage);
|
||||
}
|
||||
}
|
||||
|
||||
function ready() {
|
||||
alert("READY");
|
||||
}
|
||||
|
||||
let _port = null;
|
||||
let responseReceived = false;
|
||||
|
||||
function onmessage(message) {
|
||||
responseReceived = (message.data == "response");
|
||||
ok(responseReceived, "response received");
|
||||
}
|
||||
|
||||
function onclose() {
|
||||
ok(true, "onclose received");
|
||||
if (responseReceived) {
|
||||
ready();
|
||||
}
|
||||
}
|
||||
|
||||
(function makeConnection() {
|
||||
ok(true, "Connecting");
|
||||
navigator.mozApps.getSelf().onsuccess = event => {
|
||||
ok(true, "Got self");
|
||||
let app = event.target.result;
|
||||
app.connect("a-connection").then(ports => {
|
||||
if (!ports || !ports.length) {
|
||||
return ok(false, "No ports");
|
||||
}
|
||||
ok(true, "Got port");
|
||||
_port = ports[0];
|
||||
_port.onmessage = onmessage;
|
||||
_port.onclose = onclose;
|
||||
_port.postMessage('something');
|
||||
}).catch(error => {
|
||||
ok(false, "Unexpected " + error);
|
||||
});
|
||||
};
|
||||
})();
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"name": "IAC publisher app",
|
||||
"launch_path": "/index.html",
|
||||
"package_path": "publisher.zip",
|
||||
"type": "certified"
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
Content-Type: application/x-web-app-manifest+json
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Subscriber app for IAC API</title>
|
||||
<script src="test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "IAC subscriber app",
|
||||
"launch_path": "/index.html",
|
||||
"type": "certified",
|
||||
"connections": {
|
||||
"a-connection": {
|
||||
"description": "A connection",
|
||||
"rules": {}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
manifest.webapp
|
||||
index.html
|
||||
test.js
|
Двоичный файл не отображается.
|
@ -0,0 +1,9 @@
|
|||
let port;
|
||||
navigator.mozSetMessageHandler('connection', request => {
|
||||
port = request.port;
|
||||
port.onmessage = () => {
|
||||
port.postMessage('response');
|
||||
port.close();
|
||||
};
|
||||
});
|
||||
alert('READY');
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "IAC subscriber app",
|
||||
"launch_path": "/index.html",
|
||||
"type": "certified",
|
||||
"package_path": "subscriber.zip",
|
||||
"connections": {
|
||||
"a-connection": {
|
||||
"description": "A connection",
|
||||
"rules": {}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
Content-Type: application/x-web-app-manifest+json
|
|
@ -46,6 +46,7 @@ skip-if = os == "android" || toolkit == "gonk" || e10s # embed-apps doesn't work
|
|||
[test_bug_795164.html]
|
||||
[test_bug_1168300.html]
|
||||
skip-if = toolkit == "gonk" || e10s # see bug 1175784
|
||||
[test_checkInstalled.html]
|
||||
[test_import_export.html]
|
||||
[test_install_dev_mode.html]
|
||||
[test_install_multiple_apps_origin.html]
|
||||
|
@ -69,4 +70,3 @@ skip-if = os == "android" || toolkit == "gonk" || e10s # embed-apps doesn't work
|
|||
skip-if = os == "android" || toolkit == "gonk" || e10s # embed-apps doesn't work in mochitest app
|
||||
[test_widget_browser.html]
|
||||
skip-if = os == "android" || toolkit == "gonk" || e10s # embed-apps doesn't work in mochitest app
|
||||
[test_checkInstalled.html]
|
||||
|
|
|
@ -0,0 +1,237 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=915880
|
||||
-->
|
||||
<head>
|
||||
<title>Test for IAC API</title>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/chrome-harness.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="http://test/chrome/dom/activities/tests/mochi/common.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id={915880}">Mozilla Bug {915880}</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript;version=1.7">
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
const gURL = "http://test/chrome/dom/apps/tests/iac/";
|
||||
const IAC_UI_GLUE_CID =
|
||||
Components.ID("{384afeee-f1d2-4819-9d2e-9b62f6b0e382}");
|
||||
|
||||
function registerComponent(aObject, aDescription, aContract, aCid) {
|
||||
info("Registering " + aCid);
|
||||
|
||||
var componentManager =
|
||||
Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.registerFactory(aCid, aDescription, aContract, aObject);
|
||||
|
||||
// Keep the id on the object so we can unregister later.
|
||||
aObject.cid = aCid;
|
||||
}
|
||||
|
||||
function unregisterComponent(aObject) {
|
||||
info("Unregistering " + aObject.cid);
|
||||
var componentManager =
|
||||
Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
componentManager.unregisterFactory(aObject.cid, aObject);
|
||||
}
|
||||
|
||||
let InterAppCommUIGlue = {
|
||||
// nsISupports implementation.
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISupports) ||
|
||||
iid.equals(Ci.nsIFactory) ||
|
||||
iid.equals(Ci.nsIInterAppCommUIGlue)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
// nsIFactory implementation.
|
||||
createInstance: function(outer, iid) {
|
||||
return this.QueryInterface(iid);
|
||||
},
|
||||
|
||||
// nsIInterAppCommUIGlue implementation
|
||||
selectApps(aCallerID, aPubAppManifestURL, aKeyword, aAppsToSelect) {
|
||||
return Promise.resolve({
|
||||
callerID: aCallerID,
|
||||
keyword: aKeyword,
|
||||
manifestURL: aPubAppManifestURL,
|
||||
selectedApps: aAppsToSelect
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
registerComponent(InterAppCommUIGlue,
|
||||
"InterAppComm UI Glue",
|
||||
"@mozilla.org/dom/apps/inter-app-comm-ui-glue;1",
|
||||
IAC_UI_GLUE_CID);
|
||||
|
||||
function finish() {
|
||||
unregisterComponent(InterAppCommUIGlue);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
function cbError(aEvent) {
|
||||
ok(false, "Error callback invoked " +
|
||||
aEvent.target.error.name + " " + aEvent.target.error.message);
|
||||
finish();
|
||||
}
|
||||
|
||||
let subscriber = null;
|
||||
let publisher = null;
|
||||
|
||||
function installApp(path) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let request = navigator.mozApps.installPackage(gURL + path);
|
||||
request.onerror = () => {
|
||||
ok(false, request.error.name);
|
||||
reject();
|
||||
};
|
||||
request.onsuccess = () => {
|
||||
let app = request.result;
|
||||
ok(app, "App is not null");
|
||||
if (app.installState == "installed") {
|
||||
return resolve(app);
|
||||
}
|
||||
app.ondownloadapplied = () => {
|
||||
resolve(app);
|
||||
};
|
||||
app.ondownloaderror = () => {
|
||||
ok(false, "Unexpected download error");
|
||||
reject();
|
||||
};
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function launchApp(app) {
|
||||
if (!app) {
|
||||
ok(false, "No app to launch");
|
||||
return Promise.reject();
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
let iframe = document.createElement("iframe");
|
||||
iframe.setAttribute("mozbrowser", "true");
|
||||
iframe.setAttribute("mozapp", app.manifestURL);
|
||||
iframe.addEventListener("mozbrowsershowmodalprompt", e => {
|
||||
let message = e.detail.message;
|
||||
if (/OK/.exec(message)) {
|
||||
ok(true, "Message from app: " + message);
|
||||
} else if (/KO/.exec(message)) {
|
||||
ok(false, "Message from app: " + message);
|
||||
} else if (/READY/.exec(message)) {
|
||||
ok(true, "Message from app: " + message);
|
||||
resolve();
|
||||
} else {
|
||||
ok(false, "Unexpected message received: " + message);
|
||||
}
|
||||
}, false);
|
||||
let domParent = document.getElementById("container");
|
||||
domParent.appendChild(iframe);
|
||||
SpecialPowers.wrap(iframe.contentWindow).location =
|
||||
app.origin + app.manifest.launch_path;
|
||||
});
|
||||
}
|
||||
|
||||
const tests = [() => {
|
||||
info("Test start");
|
||||
SpecialPowers.setAllAppsLaunchable(true);
|
||||
SpecialPowers.autoConfirmAppInstall(() => {
|
||||
SpecialPowers.autoConfirmAppUninstall(next);
|
||||
});
|
||||
}, () => {
|
||||
info("Installing subscriber app");
|
||||
installApp("subscriber/update.webapp").then(app => {
|
||||
subscriber = app;
|
||||
next();
|
||||
}).catch(() => {
|
||||
ok(false, "Unable to install app");
|
||||
finish();
|
||||
});
|
||||
}, () => {
|
||||
info("Launching " + subscriber.manifest.name);
|
||||
launchApp(subscriber).then(next);
|
||||
}, () => {
|
||||
info("Installing publisher app");
|
||||
installApp("publisher/update.webapp").then(app => {
|
||||
publisher = app;
|
||||
next();
|
||||
}).catch(() => {
|
||||
ok(false, "Unable to install app");
|
||||
finish();
|
||||
});
|
||||
}, () => {
|
||||
info("Launching " + publisher.manifest.name);
|
||||
launchApp(publisher).then(next);
|
||||
}, () => {
|
||||
navigator.mozApps.mgmt.onuninstall = event => {
|
||||
let app = event.application;
|
||||
next();
|
||||
};
|
||||
let request = navigator.mozApps.mgmt.uninstall(subscriber);
|
||||
request.onerror = cbError;
|
||||
}, () => {
|
||||
navigator.mozApps.mgmt.onuninstall = event => {
|
||||
let app = event.application;
|
||||
next();
|
||||
};
|
||||
let request = navigator.mozApps.mgmt.uninstall(publisher);
|
||||
request.onerror = cbError;
|
||||
}];
|
||||
|
||||
const next = () => {
|
||||
let step = tests.shift();
|
||||
if (!step) {
|
||||
return finish();
|
||||
}
|
||||
try {
|
||||
step();
|
||||
} catch(e) {
|
||||
ok(false, "Test threw: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
SpecialPowers.pushPermissions([{
|
||||
"type": "webapps-manage",
|
||||
"allow": 1,
|
||||
"context": document
|
||||
}, {
|
||||
"type": "browser",
|
||||
"allow": 1,
|
||||
"context": document
|
||||
}, {
|
||||
"type": "embed-apps",
|
||||
"allow": 1,
|
||||
"context": document
|
||||
}], () => {
|
||||
// IAC is only allowed for certified apps. We use dev mode to
|
||||
// skip the security checks.
|
||||
SpecialPowers.pushPrefEnv({
|
||||
"set": [
|
||||
["dom.mozApps.debug", true],
|
||||
["dom.apps.developer_mode", true],
|
||||
["dom.mozBrowserFramesEnabled", true],
|
||||
["dom.sysmsg.enabled", true]
|
||||
]
|
||||
}, next);
|
||||
});
|
||||
|
||||
</script>
|
||||
<div id="container"></div>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -155,7 +155,7 @@ var steps = [
|
|||
PackagedTestHelper.gAppName);
|
||||
},
|
||||
function() {
|
||||
PackagedTestHelper.setAppVersion(1, PackagedTestHelper.next);
|
||||
PackagedTestHelper.setAppVersion(1, PackagedTestHelper.next);
|
||||
},
|
||||
function() {
|
||||
// Test mini-manifest app name is different from the webapp manifest name.
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "mozilla/dom/Event.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
using mozilla::dom::AnyCallback;
|
||||
using mozilla::dom::DOMError;
|
||||
|
@ -206,14 +207,16 @@ DOMRequest::RootResultVal()
|
|||
mozilla::HoldJSObjects(this);
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
void
|
||||
DOMRequest::Then(JSContext* aCx, AnyCallback* aResolveCallback,
|
||||
AnyCallback* aRejectCallback, mozilla::ErrorResult& aRv)
|
||||
AnyCallback* aRejectCallback,
|
||||
JS::MutableHandle<JS::Value> aRetval,
|
||||
mozilla::ErrorResult& aRv)
|
||||
{
|
||||
if (!mPromise) {
|
||||
mPromise = Promise::Create(DOMEventTargetHelper::GetParentObject(), aRv);
|
||||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
return;
|
||||
}
|
||||
if (mDone) {
|
||||
// Since we create mPromise lazily, it's possible that the DOMRequest object
|
||||
|
@ -228,7 +231,10 @@ DOMRequest::Then(JSContext* aCx, AnyCallback* aResolveCallback,
|
|||
}
|
||||
}
|
||||
|
||||
return mPromise->Then(aCx, aResolveCallback, aRejectCallback, aRv);
|
||||
// Just use the global of the Promise itself as the callee global.
|
||||
JS::Rooted<JSObject*> global(aCx, mPromise->GetWrapper());
|
||||
global = js::GetGlobalForObjectCrossCompartment(global);
|
||||
mPromise->Then(aCx, global, aResolveCallback, aRejectCallback, aRetval, aRv);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(DOMRequestService, nsIDOMRequestService)
|
||||
|
|
|
@ -74,9 +74,11 @@ public:
|
|||
IMPL_EVENT_HANDLER(success)
|
||||
IMPL_EVENT_HANDLER(error)
|
||||
|
||||
already_AddRefed<mozilla::dom::Promise>
|
||||
void
|
||||
Then(JSContext* aCx, AnyCallback* aResolveCallback,
|
||||
AnyCallback* aRejectCallback, mozilla::ErrorResult& aRv);
|
||||
AnyCallback* aRejectCallback,
|
||||
JS::MutableHandle<JS::Value> aRetval,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
void FireSuccess(JS::Handle<JS::Value> aResult);
|
||||
void FireError(const nsAString& aError);
|
||||
|
|
|
@ -3606,11 +3606,11 @@ Element::FontSizeInflation()
|
|||
}
|
||||
|
||||
net::ReferrerPolicy
|
||||
Element::GetReferrerPolicy()
|
||||
Element::GetReferrerPolicyAsEnum()
|
||||
{
|
||||
if (Preferences::GetBool("network.http.enablePerElementReferrer", false) &&
|
||||
IsHTMLElement()) {
|
||||
const nsAttrValue* referrerValue = GetParsedAttr(nsGkAtoms::referrer);
|
||||
const nsAttrValue* referrerValue = GetParsedAttr(nsGkAtoms::referrerpolicy);
|
||||
if (referrerValue && referrerValue->Type() == nsAttrValue::eEnum) {
|
||||
return net::ReferrerPolicy(referrerValue->GetEnumValue());
|
||||
}
|
||||
|
|
|
@ -1074,7 +1074,7 @@ public:
|
|||
*/
|
||||
float FontSizeInflation();
|
||||
|
||||
net::ReferrerPolicy GetReferrerPolicy();
|
||||
net::ReferrerPolicy GetReferrerPolicyAsEnum();
|
||||
|
||||
protected:
|
||||
/*
|
||||
|
|
|
@ -168,7 +168,7 @@ PerformanceObserver::Observe(const PerformanceObserverInit& aOptions,
|
|||
return;
|
||||
}
|
||||
|
||||
mEntryTypes = validEntryTypes;
|
||||
mEntryTypes.SwapElements(validEntryTypes);
|
||||
|
||||
mPerformance->AddObserver(this);
|
||||
mConnected = true;
|
||||
|
|
|
@ -184,8 +184,6 @@ ThirdPartyUtil::IsThirdPartyChannel(nsIChannel* aChannel,
|
|||
|
||||
nsresult rv;
|
||||
bool doForce = false;
|
||||
bool checkWindowChain = true;
|
||||
bool parentIsThird = false;
|
||||
nsCOMPtr<nsIHttpChannelInternal> httpChannelInternal =
|
||||
do_QueryInterface(aChannel);
|
||||
if (httpChannelInternal) {
|
||||
|
@ -203,109 +201,50 @@ ThirdPartyUtil::IsThirdPartyChannel(nsIChannel* aChannel,
|
|||
*aResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (flags & nsIHttpChannelInternal::THIRD_PARTY_PARENT_IS_THIRD_PARTY) {
|
||||
// Check that the two PARENT_IS_{THIRD,SAME}_PARTY are mutually exclusive.
|
||||
MOZ_ASSERT(!(flags & nsIHttpChannelInternal::THIRD_PARTY_PARENT_IS_SAME_PARTY));
|
||||
|
||||
// If we're not forcing and we know that the window chain of the channel
|
||||
// is third party, then we know now that we're third party.
|
||||
if (!doForce) {
|
||||
*aResult = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
checkWindowChain = false;
|
||||
parentIsThird = true;
|
||||
} else {
|
||||
// In e10s, we can't check the parent chain in the parent, so we do so
|
||||
// in the child and send the result to the parent.
|
||||
// Note that we only check the window chain if neither
|
||||
// THIRD_PARTY_PARENT_IS_* flag is set.
|
||||
checkWindowChain = !(flags & nsIHttpChannelInternal::THIRD_PARTY_PARENT_IS_SAME_PARTY);
|
||||
parentIsThird = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool parentIsThird = false;
|
||||
|
||||
// Obtain the URI from the channel, and its base domain.
|
||||
nsCOMPtr<nsIURI> channelURI;
|
||||
aChannel->GetURI(getter_AddRefs(channelURI));
|
||||
NS_ENSURE_TRUE(channelURI, NS_ERROR_INVALID_ARG);
|
||||
rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(channelURI));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCString channelDomain;
|
||||
rv = GetBaseDomain(channelURI, channelDomain);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (aURI) {
|
||||
// Determine whether aURI is foreign with respect to channelURI.
|
||||
bool result;
|
||||
rv = IsThirdPartyInternal(channelDomain, aURI, &result);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// If it's foreign, or we're forcing, we're done.
|
||||
if (result || doForce) {
|
||||
*aResult = result;
|
||||
return NS_OK;
|
||||
if (!doForce) {
|
||||
if (nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo()) {
|
||||
parentIsThird = loadInfo->GetIsInThirdPartyContext();
|
||||
if (!parentIsThird &&
|
||||
loadInfo->GetExternalContentPolicyType() != nsIContentPolicy::TYPE_DOCUMENT) {
|
||||
// Check if the channel itself is third-party to its own requestor.
|
||||
// Unforunately, we have to go through the loading principal.
|
||||
nsCOMPtr<nsIURI> parentURI;
|
||||
loadInfo->LoadingPrincipal()->GetURI(getter_AddRefs(parentURI));
|
||||
rv = IsThirdPartyInternal(channelDomain, parentURI, &parentIsThird);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
} else {
|
||||
NS_WARNING("Found channel with no loadinfo, assuming third-party request");
|
||||
parentIsThird = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If we've already computed this in the child process, we're done.
|
||||
if (!checkWindowChain) {
|
||||
// If we're not comparing to a URI, we have our answer. Otherwise, if
|
||||
// parentIsThird, we're not forcing and we know that we're a third-party
|
||||
// request.
|
||||
if (!aURI || parentIsThird) {
|
||||
*aResult = parentIsThird;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Find the associated window and its parent window.
|
||||
nsCOMPtr<nsILoadContext> ctx;
|
||||
NS_QueryNotificationCallbacks(aChannel, ctx);
|
||||
if (!ctx) return NS_ERROR_INVALID_ARG;
|
||||
|
||||
// If there is no window, the consumer kicking off the load didn't provide one
|
||||
// to the channel. This is limited to loads of certain types of resources. If
|
||||
// those loads require cookies, the forceAllowThirdPartyCookie property should
|
||||
// be set on the channel.
|
||||
nsCOMPtr<nsIDOMWindow> ourWin, parentWin;
|
||||
ctx->GetAssociatedWindow(getter_AddRefs(ourWin));
|
||||
if (!ourWin) return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> piOurWin = do_QueryInterface(ourWin);
|
||||
MOZ_ASSERT(piOurWin);
|
||||
|
||||
// We use GetScriptableParent rather than GetParent because we consider
|
||||
// <iframe mozbrowser/mozapp> to be a top-level frame.
|
||||
parentWin = piOurWin->GetScriptableParent();
|
||||
NS_ENSURE_TRUE(parentWin, NS_ERROR_INVALID_ARG);
|
||||
|
||||
// Check whether this is the document channel for this window (representing a
|
||||
// load of a new page). In that situation we want to avoid comparing
|
||||
// channelURI to ourWin, since what's in ourWin right now will be replaced as
|
||||
// the channel loads. This covers the case of a freshly kicked-off load
|
||||
// (e.g. the user typing something in the location bar, or clicking on a
|
||||
// bookmark), where the window's URI hasn't yet been set, and will be bogus.
|
||||
// It also covers situations where a subframe is navigated to someting that
|
||||
// is same-origin with all its ancestors. This is a bit of a nasty hack, but
|
||||
// we will hopefully flag these channels better later.
|
||||
nsLoadFlags flags;
|
||||
rv = aChannel->GetLoadFlags(&flags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (flags & nsIChannel::LOAD_DOCUMENT_URI) {
|
||||
if (SameCOMIdentity(ourWin, parentWin)) {
|
||||
// We only need to compare aURI to the channel URI -- the window's will be
|
||||
// bogus. We already know the answer.
|
||||
*aResult = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Make sure to still compare to ourWin's ancestors
|
||||
ourWin = parentWin;
|
||||
}
|
||||
|
||||
// Check the window hierarchy. This covers most cases for an ordinary page
|
||||
// load from the location bar.
|
||||
return IsThirdPartyWindow(ourWin, channelURI, aResult);
|
||||
// Determine whether aURI is foreign with respect to channelURI.
|
||||
return IsThirdPartyInternal(channelDomain, aURI, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -12,9 +12,7 @@
|
|||
//
|
||||
// (b) a comment, which is a line that begins with "//"
|
||||
//
|
||||
// (c) an #if/ifdef/else/endif preprocessor directive
|
||||
//
|
||||
// (d) one of three possible use counter declarations:
|
||||
// (c) one of three possible use counter declarations:
|
||||
//
|
||||
// method <IDL interface name>.<IDL operation name>
|
||||
// attribute <IDL interface name>.<IDL attribute name>
|
||||
|
|
|
@ -846,8 +846,7 @@ nsDOMMutationObserver::HandleMutation()
|
|||
}
|
||||
ClearPendingRecords();
|
||||
|
||||
mozilla::ErrorResult rv;
|
||||
mCallback->Call(this, mutations, *this, rv);
|
||||
mCallback->Call(this, mutations, *this);
|
||||
}
|
||||
|
||||
class AsyncMutationHandler : public nsRunnable
|
||||
|
|
|
@ -1438,18 +1438,44 @@ nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection)
|
|||
break;
|
||||
}
|
||||
#ifdef MOZ_THUNDERBIRD
|
||||
else if (selContent->IsElement()) {
|
||||
RefPtr<nsStyleContext> styleContext =
|
||||
nsComputedDOMStyle::GetStyleContextForElementNoFlush(
|
||||
selContent->AsElement(), nullptr, nullptr);
|
||||
if (styleContext) {
|
||||
const nsStyleText* textStyle = styleContext->StyleText();
|
||||
if (textStyle->mWhiteSpace == NS_STYLE_WHITESPACE_PRE_WRAP) {
|
||||
mIsTextWidget = true;
|
||||
}
|
||||
else if (selContent->IsHTMLElement(nsGkAtoms::body)) {
|
||||
// Currently, setting mIsTextWidget to 'true' will result in the selection
|
||||
// being encoded/copied as pre-formatted plain text.
|
||||
// This is fine for copying pre-formatted plain text with Firefox, it is
|
||||
// already not correct for copying pre-formatted "rich" text (bold, colour)
|
||||
// with Firefox. As long as the serialisers aren't fixed, copying
|
||||
// pre-formatted text in Firefox is broken. If we set mIsTextWidget,
|
||||
// pre-formatted plain text is copied, but pre-formatted "rich" text loses
|
||||
// the "rich" formatting. If we don't set mIsTextWidget, "rich" text
|
||||
// attributes aren't lost, but white-space is lost.
|
||||
// So far the story for Firefox.
|
||||
//
|
||||
// Thunderbird has two *conflicting* requirements.
|
||||
// Case 1:
|
||||
// When selecting and copying text, even pre-formatted text, as a quote
|
||||
// to be placed into a reply, we *always* expect HTML to be copied.
|
||||
// Case 2:
|
||||
// When copying text in a so-called "plain text" message, that is
|
||||
// one where the body carries style "white-space:pre-wrap", the text should
|
||||
// be copied as pre-formatted plain text.
|
||||
//
|
||||
// Therefore the following code checks for "pre-wrap" on the body.
|
||||
// This is a terrible hack.
|
||||
//
|
||||
// The proper fix would be this:
|
||||
// For case 1:
|
||||
// Communicate the fact that HTML is required to EncodeToString(),
|
||||
// bug 1141786.
|
||||
// For case 2:
|
||||
// Wait for Firefox to get fixed to detect pre-formatting correctly,
|
||||
// bug 1174452.
|
||||
nsAutoString styleVal;
|
||||
if (selContent->GetAttr(kNameSpaceID_None, nsGkAtoms::style, styleVal) &&
|
||||
styleVal.Find(NS_LITERAL_STRING("pre-wrap")) != kNotFound) {
|
||||
mIsTextWidget = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -411,7 +411,7 @@ nsFrameLoader::ReallyStartLoadingInternal()
|
|||
net::ReferrerPolicy referrerPolicy = mOwnerContent->OwnerDoc()->GetReferrerPolicy();
|
||||
HTMLIFrameElement* iframe = HTMLIFrameElement::FromContent(mOwnerContent);
|
||||
if (iframe) {
|
||||
net::ReferrerPolicy iframeReferrerPolicy = iframe->GetReferrerPolicy();
|
||||
net::ReferrerPolicy iframeReferrerPolicy = iframe->GetReferrerPolicyAsEnum();
|
||||
if (iframeReferrerPolicy != net::RP_Unset) {
|
||||
referrerPolicy = iframeReferrerPolicy;
|
||||
}
|
||||
|
|
|
@ -594,6 +594,7 @@ GK_ATOM(menuseparator, "menuseparator")
|
|||
GK_ATOM(message, "message")
|
||||
GK_ATOM(meta, "meta")
|
||||
GK_ATOM(referrer, "referrer")
|
||||
GK_ATOM(referrerpolicy, "referrerpolicy")
|
||||
GK_ATOM(meter, "meter")
|
||||
GK_ATOM(method, "method")
|
||||
GK_ATOM(microdataProperties, "microdataProperties")
|
||||
|
|
|
@ -1668,7 +1668,8 @@ nsXMLHttpRequest::Open(const nsACString& inMethod, const nsACString& url,
|
|||
nsCOMPtr<nsILoadGroup> loadGroup = GetLoadGroup();
|
||||
|
||||
nsSecurityFlags secFlags;
|
||||
nsLoadFlags loadFlags = nsIRequest::LOAD_BACKGROUND;
|
||||
nsLoadFlags loadFlags = nsIRequest::LOAD_BACKGROUND |
|
||||
nsIChannel::LOAD_CLASSIFY_URI;
|
||||
if (nsContentUtils::IsSystemPrincipal(mPrincipal)) {
|
||||
// When chrome is loading we want to make sure to sandbox any potential
|
||||
// result document. We also want to allow cross-origin loads.
|
||||
|
|
|
@ -14,7 +14,7 @@ function createTestPage(aHead, aImgPolicy, aName) {
|
|||
<html>'+
|
||||
aHead +
|
||||
'<body>\n\
|
||||
<img src="' + _createTestUrl('img') + '" referrer="' + aImgPolicy + '" id="image"></img>\n\
|
||||
<img src="' + _createTestUrl('img') + '" referrerpolicy="' + aImgPolicy + '" id="image"></img>\n\
|
||||
<script>' +
|
||||
|
||||
// LOAD EVENT (of the test)
|
||||
|
@ -52,9 +52,9 @@ function createTest3(aImgPolicy1, aImgPolicy2, aImgPolicy3, aName) {
|
|||
return '<!DOCTYPE HTML>\n\
|
||||
<html>\n\
|
||||
<body>\n\
|
||||
<img src="' + createTestUrl(aImgPolicy1, 'test', aName + aImgPolicy1) + '" referrer="' + aImgPolicy1 + '" id="image"></img>\n\
|
||||
<img src="' + createTestUrl(aImgPolicy2, 'test', aName + aImgPolicy2) + '" referrer="' + aImgPolicy2 + '" id="image"></img>\n\
|
||||
<img src="' + createTestUrl(aImgPolicy3, 'test', aName + aImgPolicy3) + '" referrer="' + aImgPolicy3 + '" id="image"></img>\n\
|
||||
<img src="' + createTestUrl(aImgPolicy1, 'test', aName + aImgPolicy1) + '" referrerpolicy="' + aImgPolicy1 + '" id="image"></img>\n\
|
||||
<img src="' + createTestUrl(aImgPolicy2, 'test', aName + aImgPolicy2) + '" referrerpolicy="' + aImgPolicy2 + '" id="image"></img>\n\
|
||||
<img src="' + createTestUrl(aImgPolicy3, 'test', aName + aImgPolicy3) + '" referrerpolicy="' + aImgPolicy3 + '" id="image"></img>\n\
|
||||
<script>\n\
|
||||
var _numLoads = 0;' +
|
||||
|
||||
|
|
|
@ -33,11 +33,11 @@ function createIframeTestPageUsingRefferer(aMetaPolicy, aAttributePolicy, aNewAt
|
|||
}
|
||||
var changeString = "";
|
||||
if (aChangingMethod === "setAttribute") {
|
||||
changeString = `document.getElementById("myframe").setAttribute("referrer", "${aNewAttributePolicy}")`;
|
||||
changeString = `document.getElementById("myframe").setAttribute("referrerpolicy", "${aNewAttributePolicy}")`;
|
||||
} else if (aChangingMethod === "property") {
|
||||
changeString = `document.getElementById("myframe").referrer = "${aNewAttributePolicy}"`;
|
||||
changeString = `document.getElementById("myframe").referrerPolicy = "${aNewAttributePolicy}"`;
|
||||
}
|
||||
var iFrameString = `<iframe src="" id="myframe" ${aAttributePolicy ? ` referrer="${aAttributePolicy}"` : ""}>iframe</iframe>`;
|
||||
var iFrameString = `<iframe src="" id="myframe" ${aAttributePolicy ? ` referrerpolicy="${aAttributePolicy}"` : ""}>iframe</iframe>`;
|
||||
var iframeUrl = "";
|
||||
if (aParams) {
|
||||
aParams.delete("ACTION");
|
||||
|
@ -69,7 +69,7 @@ function createIframeTestPageUsingRefferer(aMetaPolicy, aAttributePolicy, aNewAt
|
|||
|
||||
function buildAnchorString(aMetaPolicy, aReferrerPolicy, aName, aRelString){
|
||||
if (aReferrerPolicy) {
|
||||
return `<a href="${createTestUrl(aReferrerPolicy, 'test', aName, 'link')}" referrer="${aReferrerPolicy}" id="link" ${aRelString}>${aReferrerPolicy}</a>`;
|
||||
return `<a href="${createTestUrl(aReferrerPolicy, 'test', aName, 'link')}" referrerpolicy="${aReferrerPolicy}" id="link" ${aRelString}>${aReferrerPolicy}</a>`;
|
||||
}
|
||||
return `<a href="${createTestUrl(aMetaPolicy, 'test', aName, 'link')}" id="link" ${aRelString}>link</a>`;
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ function buildAreaString(aMetaPolicy, aReferrerPolicy, aName, aRelString){
|
|||
var result = `<img src="file_mozfiledataurl_img.jpg" alt="image" usemap="#imageMap">`;
|
||||
result += `<map name="imageMap">`;
|
||||
if (aReferrerPolicy) {
|
||||
result += `<area shape="circle" coords="1,1,1" href="${createTestUrl(aReferrerPolicy, 'test', aName, 'link')}" alt="theArea" referrer="${aReferrerPolicy}" id="link" ${aRelString}>`;
|
||||
result += `<area shape="circle" coords="1,1,1" href="${createTestUrl(aReferrerPolicy, 'test', aName, 'link')}" alt="theArea" referrerpolicy="${aReferrerPolicy}" id="link" ${aRelString}>`;
|
||||
} else {
|
||||
result += `<area shape="circle" coords="1,1,1" href="${createTestUrl(aMetaPolicy, 'test', aName, 'link')}" alt="theArea" id="link" ${aRelString}>`;
|
||||
}
|
||||
|
@ -95,9 +95,9 @@ function createAETestPageUsingRefferer(aMetaPolicy, aAttributePolicy, aNewAttrib
|
|||
}
|
||||
var changeString = "";
|
||||
if (aChangingMethod === "setAttribute") {
|
||||
changeString = `document.getElementById("link").setAttribute("referrer", "${aNewAttributePolicy}")`;
|
||||
changeString = `document.getElementById("link").setAttribute("referrerpolicy", "${aNewAttributePolicy}")`;
|
||||
} else if (aChangingMethod === "property") {
|
||||
changeString = `document.getElementById("link").referrer = "${aNewAttributePolicy}"`;
|
||||
changeString = `document.getElementById("link").referrerPolicy = "${aNewAttributePolicy}"`;
|
||||
}
|
||||
var relString = "";
|
||||
if (aRel) {
|
||||
|
@ -138,7 +138,7 @@ function createRedirectImgTestCase(aParams, aAttributePolicy) {
|
|||
<title>Test referrer policies on redirect (img)</title>
|
||||
</head>
|
||||
<body>
|
||||
<img id="testImg" src="${imgUrl}" ${aAttributePolicy ? ` referrer="${aAttributePolicy}"` : ""}>
|
||||
<img id="testImg" src="${imgUrl}" ${aAttributePolicy ? ` referrerpolicy="${aAttributePolicy}"` : ""}>
|
||||
<script>
|
||||
window.addEventListener("load", function() {
|
||||
parent.postMessage("childLoadComplete", "http://mochi.test:8888");
|
||||
|
|
|
@ -67,17 +67,17 @@ function run_test() {
|
|||
NS_ERROR_INVALID_ARG);
|
||||
|
||||
// We can't test isThirdPartyWindow since we can't really set up a window
|
||||
// heirarchy. We leave that to mochitests.
|
||||
// hierarchy. We leave that to mochitests.
|
||||
|
||||
// Test isThirdPartyChannel. As above, we can't test the bits that require
|
||||
// a load context or window heirarchy.
|
||||
// a load context or window heirarchy. Because of that, the code assumes
|
||||
// that these are all third-party loads.
|
||||
do_check_throws(function() { util.isThirdPartyChannel(null); },
|
||||
NS_ERROR_INVALID_ARG);
|
||||
do_check_throws(function() { util.isThirdPartyChannel(channel1); },
|
||||
NS_ERROR_INVALID_ARG);
|
||||
do_check_throws(function() { util.isThirdPartyChannel(channel1, uri1); },
|
||||
NS_ERROR_INVALID_ARG);
|
||||
do_check_true(util.isThirdPartyChannel(channel1));
|
||||
do_check_true(util.isThirdPartyChannel(channel1, uri1));
|
||||
do_check_true(util.isThirdPartyChannel(channel1, uri2));
|
||||
|
||||
let httpchannel1 = channel1.QueryInterface(Ci.nsIHttpChannelInternal);
|
||||
httpchannel1.forceAllowThirdPartyCookie = true;
|
||||
do_check_false(util.isThirdPartyChannel(channel1));
|
||||
|
|
|
@ -8,18 +8,9 @@ import re
|
|||
import StringIO
|
||||
import sys
|
||||
|
||||
from mozbuild.preprocessor import preprocess
|
||||
|
||||
def read_conf(conf_filename):
|
||||
# Invoking the preprocessor ourselves is easier than writing build rules
|
||||
# to do it for us.
|
||||
processed = StringIO.StringIO()
|
||||
preprocess(includes=[conf_filename],
|
||||
defines=buildconfig.defines,
|
||||
output=processed)
|
||||
|
||||
# Can't read/write from a single StringIO, so make a new one for reading.
|
||||
stream = StringIO.StringIO(processed.getvalue())
|
||||
stream = open(conf_filename, 'rU')
|
||||
|
||||
def parse_counters(stream):
|
||||
for line_num, line in enumerate(stream):
|
||||
|
|
|
@ -2761,8 +2761,17 @@ ConvertExceptionToPromise(JSContext* cx,
|
|||
}
|
||||
|
||||
JS_ClearPendingException(cx);
|
||||
|
||||
nsCOMPtr<nsIGlobalObject> globalObj =
|
||||
do_QueryInterface(global.GetAsSupports());
|
||||
if (!globalObj) {
|
||||
ErrorResult rv;
|
||||
rv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return !rv.MaybeSetPendingException(cx);
|
||||
}
|
||||
|
||||
ErrorResult rv;
|
||||
RefPtr<Promise> promise = Promise::Reject(global, exn, rv);
|
||||
RefPtr<Promise> promise = Promise::Reject(globalObj, cx, exn, rv);
|
||||
if (rv.MaybeSetPendingException(cx)) {
|
||||
// We just give up. We put the exception from the ErrorResult on
|
||||
// the JSContext just to make sure to not leak memory on the
|
||||
|
|
|
@ -1949,7 +1949,13 @@ DOMInterfaces = {
|
|||
# Keep this in sync with TestExampleInterface
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False
|
||||
}
|
||||
},
|
||||
|
||||
'TestInterfaceWithPromiseConstructorArg' : {
|
||||
'headerFile': 'TestBindingHeader.h',
|
||||
'register': False,
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
# These are temporary, until they've been converted to use new DOM bindings
|
||||
|
|
|
@ -2779,7 +2779,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
|||
for pref, ptr in prefCacheData]
|
||||
prefCache = CGWrapper(CGIndenter(CGList(prefCacheData)),
|
||||
pre=("static bool sPrefCachesInited = false;\n"
|
||||
"if (!sPrefCachesInited) {\n"
|
||||
"if (!sPrefCachesInited && NS_IsMainThread()) {\n"
|
||||
" sPrefCachesInited = true;\n"),
|
||||
post="}\n")
|
||||
else:
|
||||
|
@ -2979,6 +2979,21 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
|||
else:
|
||||
unforgeableHolderSetup = None
|
||||
|
||||
if self.descriptor.name == "Promise":
|
||||
speciesSetup = CGGeneric(fill(
|
||||
"""
|
||||
JS::Rooted<JSObject*> promiseConstructor(aCx, *interfaceCache);
|
||||
JS::Rooted<jsid> species(aCx,
|
||||
SYMBOL_TO_JSID(JS::GetWellKnownSymbol(aCx, JS::SymbolCode::species)));
|
||||
if (!JS_DefinePropertyById(aCx, promiseConstructor, species, JS::UndefinedHandleValue,
|
||||
JSPROP_SHARED, Promise::PromiseSpecies, nullptr)) {
|
||||
$*{failureCode}
|
||||
}
|
||||
""",
|
||||
failureCode=failureCode))
|
||||
else:
|
||||
speciesSetup = None
|
||||
|
||||
if (self.descriptor.interface.isOnGlobalProtoChain() and
|
||||
needInterfacePrototypeObject):
|
||||
makeProtoPrototypeImmutable = CGGeneric(fill(
|
||||
|
@ -3004,7 +3019,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
|
|||
return CGList(
|
||||
[getParentProto, CGGeneric(getConstructorProto), initIds,
|
||||
prefCache, CGGeneric(call), defineAliases, unforgeableHolderSetup,
|
||||
makeProtoPrototypeImmutable],
|
||||
speciesSetup, makeProtoPrototypeImmutable],
|
||||
"\n").define()
|
||||
|
||||
|
||||
|
@ -5078,24 +5093,124 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
|||
templateBody += 'static_assert(IsRefcounted<%s>::value, "We can only store refcounted classes.");' % typeName
|
||||
|
||||
if isPromise:
|
||||
# Per spec, what we're supposed to do is take the original
|
||||
# Promise.resolve and call it with the original Promise as this
|
||||
# value to make a Promise out of whatever value we actually have
|
||||
# here. The question is which global we should use. There are
|
||||
# several cases to consider:
|
||||
#
|
||||
# 1) Normal call to API with a Promise argument. This is a case the
|
||||
# spec covers, and we should be using the current Realm's
|
||||
# Promise. That means the current compartment.
|
||||
# 2) Call to API with a Promise argument over Xrays. In practice,
|
||||
# this sort of thing seems to be used for giving an API
|
||||
# implementation a way to wait for conclusion of an asyc
|
||||
# operation, _not_ to expose the Promise to content code. So we
|
||||
# probably want to allow callers to use such an API in a
|
||||
# "natural" way, by passing chrome-side promises; indeed, that
|
||||
# may be all that the caller has to represent their async
|
||||
# operation. That means we really need to do the
|
||||
# Promise.resolve() in the caller (chrome) compartment: if we do
|
||||
# it in the content compartment, we will try to call .then() on
|
||||
# the chrome promise while in the content compartment, which will
|
||||
# throw and we'll just get a rejected Promise. Note that this is
|
||||
# also the reason why a caller who has a chrome Promise
|
||||
# representing an async operation can't itself convert it to a
|
||||
# content-side Promise (at least not without some serious
|
||||
# gyrations).
|
||||
# 3) Promise return value from a callback or callback interface.
|
||||
# This is in theory a case the spec covers but in practice it
|
||||
# really doesn't define behavior here because it doesn't define
|
||||
# what Realm we're in after the callback returns, which is when
|
||||
# the argument conversion happens. We will use the current
|
||||
# compartment, which is the compartment of the callable (which
|
||||
# may itself be a cross-compartment wrapper itself), which makes
|
||||
# as much sense as anything else. In practice, such an API would
|
||||
# once again be providing a Promise to signal completion of an
|
||||
# operation, which would then not be exposed to anyone other than
|
||||
# our own implementation code.
|
||||
# 4) Return value from a JS-implemented interface. In this case we
|
||||
# have a problem. Our current compartment is the compartment of
|
||||
# the JS implementation. But if the JS implementation returned
|
||||
# a page-side Promise (which is a totally sane thing to do, and
|
||||
# in fact the right thing to do given that this return value is
|
||||
# going right to content script) then we don't want to
|
||||
# Promise.resolve with our current compartment Promise, because
|
||||
# that will wrap it up in a chrome-side Promise, which is
|
||||
# decidedly _not_ what's desired here. So in that case we
|
||||
# should really unwrap the return value and use the global of
|
||||
# the result. CheckedUnwrap should be good enough for that; if
|
||||
# it fails, then we're failing unwrap while in a
|
||||
# system-privileged compartment, so presumably we have a dead
|
||||
# object wrapper. Just error out. Do NOT fall back to using
|
||||
# the current compartment instead: that will return a
|
||||
# system-privileged rejected (because getting .then inside
|
||||
# resolve() failed) Promise to the caller, which they won't be
|
||||
# able to touch. That's not helpful. If we error out, on the
|
||||
# other hand, they will get a content-side rejected promise.
|
||||
# Same thing if the value returned is not even an object.
|
||||
if isCallbackReturnValue == "JSImpl":
|
||||
# Case 4 above. Note that globalObj defaults to the current
|
||||
# compartment global. Note that we don't use $*{exceptionCode}
|
||||
# here because that will try to aRv.Throw(NS_ERROR_UNEXPECTED)
|
||||
# which we don't really want here.
|
||||
assert exceptionCode == "aRv.Throw(NS_ERROR_UNEXPECTED);\nreturn nullptr;\n"
|
||||
getPromiseGlobal = fill(
|
||||
"""
|
||||
if (!$${val}.isObject()) {
|
||||
aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("${sourceDescription}"));
|
||||
return nullptr;
|
||||
}
|
||||
JSObject* unwrappedVal = js::CheckedUnwrap(&$${val}.toObject());
|
||||
if (!unwrappedVal) {
|
||||
// A slight lie, but not much of one, for a dead object wrapper.
|
||||
aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("${sourceDescription}"));
|
||||
return nullptr;
|
||||
}
|
||||
globalObj = js::GetGlobalForObjectCrossCompartment(unwrappedVal);
|
||||
""",
|
||||
sourceDescription=sourceDescription)
|
||||
else:
|
||||
getPromiseGlobal = ""
|
||||
|
||||
templateBody = fill(
|
||||
"""
|
||||
{ // Scope for our GlobalObject and ErrorResult
|
||||
{ // Scope for our GlobalObject, ErrorResult, JSAutoCompartment,
|
||||
// etc.
|
||||
|
||||
// Might as well use CurrentGlobalOrNull here; that will at
|
||||
// least give us the same behavior as if the caller just called
|
||||
// Promise.resolve() themselves.
|
||||
GlobalObject promiseGlobal(cx, JS::CurrentGlobalOrNull(cx));
|
||||
JS::Rooted<JSObject*> globalObj(cx, JS::CurrentGlobalOrNull(cx));
|
||||
$*{getPromiseGlobal}
|
||||
JSAutoCompartment ac(cx, globalObj);
|
||||
GlobalObject promiseGlobal(cx, globalObj);
|
||||
if (promiseGlobal.Failed()) {
|
||||
$*{exceptionCode}
|
||||
}
|
||||
ErrorResult promiseRv;
|
||||
$${declName} = Promise::Resolve(promiseGlobal, $${val}, promiseRv);
|
||||
JS::Handle<JSObject*> promiseCtor =
|
||||
PromiseBinding::GetConstructorObjectHandle(cx, globalObj);
|
||||
if (!promiseCtor) {
|
||||
$*{exceptionCode}
|
||||
}
|
||||
JS::Rooted<JS::Value> resolveThisv(cx, JS::ObjectValue(*promiseCtor));
|
||||
JS::Rooted<JS::Value> resolveResult(cx);
|
||||
JS::Rooted<JS::Value> valueToResolve(cx, $${val});
|
||||
if (!JS_WrapValue(cx, &valueToResolve)) {
|
||||
$*{exceptionCode}
|
||||
}
|
||||
Promise::Resolve(promiseGlobal, resolveThisv, valueToResolve,
|
||||
&resolveResult, promiseRv);
|
||||
if (promiseRv.MaybeSetPendingException(cx)) {
|
||||
$*{exceptionCode}
|
||||
}
|
||||
nsresult unwrapRv = UNWRAP_OBJECT(Promise, &resolveResult.toObject(), $${declName});
|
||||
if (NS_FAILED(unwrapRv)) { // Quite odd
|
||||
promiseRv.Throw(unwrapRv);
|
||||
promiseRv.MaybeSetPendingException(cx);
|
||||
$*{exceptionCode}
|
||||
}
|
||||
}
|
||||
""",
|
||||
getPromiseGlobal=getPromiseGlobal,
|
||||
exceptionCode=exceptionCode)
|
||||
elif not descriptor.skipGen and not descriptor.interface.isConsequential() and not descriptor.interface.isExternal():
|
||||
if failureCode is not None:
|
||||
|
@ -7032,16 +7147,59 @@ class CGPerSignatureCall(CGThing):
|
|||
if needsCx:
|
||||
argsPre.append("cx")
|
||||
|
||||
# Hack for making Promise.prototype.then work well over Xrays.
|
||||
if (not static and
|
||||
(descriptor.name == "Promise" or
|
||||
descriptor.name == "MozAbortablePromise") and
|
||||
idlNode.isMethod() and
|
||||
idlNode.identifier.name == "then"):
|
||||
cgThings.append(CGGeneric(dedent(
|
||||
"""
|
||||
JS::Rooted<JSObject*> calleeGlobal(cx, xpc::XrayAwareCalleeGlobal(&args.callee()));
|
||||
""")))
|
||||
argsPre.append("calleeGlobal")
|
||||
|
||||
needsUnwrap = False
|
||||
argsPost = []
|
||||
if isConstructor:
|
||||
needsUnwrap = True
|
||||
needsUnwrappedVar = False
|
||||
unwrappedVar = "obj"
|
||||
if descriptor.name == "Promise" or descriptor.name == "MozAbortablePromise":
|
||||
# Hack for Promise for now: pass in our desired proto so the
|
||||
# implementation can create the reflector with the right proto.
|
||||
argsPost.append("desiredProto")
|
||||
# Also, we do not want to enter the content compartment when the
|
||||
# Promise constructor is called via Xrays, because we want to
|
||||
# create our callback functions that we will hand to our caller
|
||||
# in the Xray compartment. The reason we want to do that is the
|
||||
# following situation, over Xrays:
|
||||
#
|
||||
# contentWindow.Promise.race([Promise.resolve(5)])
|
||||
#
|
||||
# Ideally this would work. Internally, race() does a
|
||||
# contentWindow.Promise.resolve() on everything in the array.
|
||||
# Per spec, to support subclassing,
|
||||
# contentWindow.Promise.resolve has to do:
|
||||
#
|
||||
# var resolve, reject;
|
||||
# var p = new contentWindow.Promise(function(a, b) {
|
||||
# resolve = a;
|
||||
# reject = b;
|
||||
# });
|
||||
# resolve(arg);
|
||||
# return p;
|
||||
#
|
||||
# where "arg" is, in this case, the chrome-side return value of
|
||||
# Promise.resolve(5). But if the "resolve" function in that
|
||||
# case were created in the content compartment, then calling it
|
||||
# would wrap "arg" in an opaque wrapper, and that function tries
|
||||
# to get .then off the argument, which would throw. So we need
|
||||
# to create the "resolve" function in the chrome compartment,
|
||||
# and hence want to be running the entire Promise constructor
|
||||
# (which creates that function) in the chrome compartment in
|
||||
# this case. So don't set needsUnwrap here.
|
||||
else:
|
||||
needsUnwrap = True
|
||||
needsUnwrappedVar = False
|
||||
unwrappedVar = "obj"
|
||||
elif descriptor.interface.isJSImplemented():
|
||||
if not idlNode.isStatic():
|
||||
needsUnwrap = True
|
||||
|
@ -7054,6 +7212,11 @@ class CGPerSignatureCall(CGThing):
|
|||
needsUnwrappedVar = True
|
||||
argsPre.append("unwrappedObj ? *unwrappedObj : obj")
|
||||
|
||||
if static and not isConstructor and descriptor.name == "Promise":
|
||||
# Hack for Promise for now: pass in the "this" value to
|
||||
# Promise static methods.
|
||||
argsPre.append("args.thisv()")
|
||||
|
||||
if needsUnwrap and needsUnwrappedVar:
|
||||
# We cannot assign into obj because it's a Handle, not a
|
||||
# MutableHandle, so we need a separate Rooted.
|
||||
|
@ -8998,26 +9161,6 @@ class CGStaticMethodJitinfo(CGGeneric):
|
|||
IDLToCIdentifier(method.identifier.name))))
|
||||
|
||||
|
||||
class CGMethodIdentityTest(CGAbstractMethod):
|
||||
"""
|
||||
A class to generate a method-identity test for a given IDL operation.
|
||||
"""
|
||||
def __init__(self, descriptor, method):
|
||||
self.method = method
|
||||
name = "Is%sMethod" % MakeNativeName(method.identifier.name)
|
||||
CGAbstractMethod.__init__(self, descriptor, name, 'bool',
|
||||
[Argument('JS::Handle<JSObject*>', 'aObj')])
|
||||
|
||||
def definition_body(self):
|
||||
return dedent(
|
||||
"""
|
||||
MOZ_ASSERT(aObj);
|
||||
return js::IsFunctionObject(aObj) &&
|
||||
js::FunctionObjectIsNative(aObj) &&
|
||||
FUNCTION_VALUE_TO_JITINFO(JS::ObjectValue(*aObj)) == &%s_methodinfo;
|
||||
""" % IDLToCIdentifier(self.method.identifier.name))
|
||||
|
||||
|
||||
def getEnumValueName(value):
|
||||
# Some enum values can be empty strings. Others might have weird
|
||||
# characters in them. Deal with the former by returning "_empty",
|
||||
|
@ -11649,8 +11792,6 @@ class CGDescriptor(CGThing):
|
|||
cgThings.append(CGMemberJITInfo(descriptor, m))
|
||||
if props.isCrossOriginMethod:
|
||||
crossOriginMethods.add(m.identifier.name)
|
||||
if m.getExtendedAttribute("MethodIdentityTestable"):
|
||||
cgThings.append(CGMethodIdentityTest(descriptor, m))
|
||||
# If we've hit the maplike/setlike member itself, go ahead and
|
||||
# generate its convenience functions.
|
||||
elif m.isMaplikeOrSetlike():
|
||||
|
@ -14385,16 +14526,33 @@ class CGCallback(CGClass):
|
|||
assert args[0].name == "cx" and args[0].argType == "JSContext*"
|
||||
assert args[1].name == "aThisVal" and args[1].argType == "JS::Handle<JS::Value>"
|
||||
args = args[2:]
|
||||
|
||||
# Now remember which index the ErrorResult argument is at;
|
||||
# we'll need this below.
|
||||
assert args[-1].name == "aRv" and args[-1].argType == "ErrorResult&"
|
||||
rvIndex = len(args) - 1
|
||||
assert rvIndex >= 0
|
||||
|
||||
# Record the names of all the arguments, so we can use them when we call
|
||||
# the private method.
|
||||
argnames = [arg.name for arg in args]
|
||||
argnamesWithThis = ["s.GetContext()", "thisValJS"] + argnames
|
||||
argnamesWithoutThis = ["s.GetContext()", "JS::UndefinedHandleValue"] + argnames
|
||||
# Now that we've recorded the argnames for our call to our private
|
||||
# method, insert our optional arguments for the execution reason and for
|
||||
# deciding whether the CallSetup should re-throw exceptions on aRv.
|
||||
# method, insert our optional argument for the execution reason.
|
||||
args.append(Argument("const char*", "aExecutionReason",
|
||||
"nullptr"))
|
||||
|
||||
# Make copies of the arg list for the two "without rv" overloads. Note
|
||||
# that those don't need aExceptionHandling or aCompartment arguments
|
||||
# because those would make not sense anyway: the only sane thing to do
|
||||
# with exceptions in the "without rv" cases is to report them.
|
||||
argsWithoutRv = list(args)
|
||||
argsWithoutRv.pop(rvIndex)
|
||||
argsWithoutThisAndRv = list(argsWithoutRv)
|
||||
|
||||
# Add the potional argument for deciding whether the CallSetup should
|
||||
# re-throw exceptions on aRv.
|
||||
args.append(Argument("ExceptionHandling", "aExceptionHandling",
|
||||
"eReportExceptions"))
|
||||
# And the argument for communicating when exceptions should really be
|
||||
|
@ -14406,6 +14564,22 @@ class CGCallback(CGClass):
|
|||
# And now insert our template argument.
|
||||
argsWithoutThis = list(args)
|
||||
args.insert(0, Argument("const T&", "thisVal"))
|
||||
argsWithoutRv.insert(0, Argument("const T&", "thisVal"))
|
||||
|
||||
argnamesWithoutThisAndRv = [arg.name for arg in argsWithoutThisAndRv]
|
||||
argnamesWithoutThisAndRv.insert(rvIndex, "rv");
|
||||
# If we just leave things like that, and have no actual arguments in the
|
||||
# IDL, we will end up trying to call the templated "without rv" overload
|
||||
# with "rv" as the thisVal. That's no good. So explicitly append the
|
||||
# aExceptionHandling and aCompartment values we need to end up matching
|
||||
# the signature of our non-templated "with rv" overload.
|
||||
argnamesWithoutThisAndRv.extend(["eReportExceptions", "nullptr"])
|
||||
|
||||
argnamesWithoutRv = [arg.name for arg in argsWithoutRv]
|
||||
# Note that we need to insert at rvIndex + 1, since we inserted a
|
||||
# thisVal arg at the start.
|
||||
argnamesWithoutRv.insert(rvIndex + 1, "rv")
|
||||
|
||||
errorReturn = method.getDefaultRetval()
|
||||
|
||||
setupCall = fill(
|
||||
|
@ -14445,6 +14619,20 @@ class CGCallback(CGClass):
|
|||
errorReturn=errorReturn,
|
||||
methodName=method.name,
|
||||
callArgs=", ".join(argnamesWithoutThis))
|
||||
bodyWithThisWithoutRv = fill(
|
||||
"""
|
||||
IgnoredErrorResult rv;
|
||||
return ${methodName}(${callArgs});
|
||||
""",
|
||||
methodName=method.name,
|
||||
callArgs=", ".join(argnamesWithoutRv))
|
||||
bodyWithoutThisAndRv = fill(
|
||||
"""
|
||||
IgnoredErrorResult rv;
|
||||
return ${methodName}(${callArgs});
|
||||
""",
|
||||
methodName=method.name,
|
||||
callArgs=", ".join(argnamesWithoutThisAndRv))
|
||||
|
||||
return [ClassMethod(method.name, method.returnType, args,
|
||||
bodyInHeader=True,
|
||||
|
@ -14453,6 +14641,13 @@ class CGCallback(CGClass):
|
|||
ClassMethod(method.name, method.returnType, argsWithoutThis,
|
||||
bodyInHeader=True,
|
||||
body=bodyWithoutThis),
|
||||
ClassMethod(method.name, method.returnType, argsWithoutRv,
|
||||
bodyInHeader=True,
|
||||
templateArgs=["typename T"],
|
||||
body=bodyWithThisWithoutRv),
|
||||
ClassMethod(method.name, method.returnType, argsWithoutThisAndRv,
|
||||
bodyInHeader=True,
|
||||
body=bodyWithoutThisAndRv),
|
||||
method]
|
||||
|
||||
def deps(self):
|
||||
|
|
|
@ -398,6 +398,16 @@ private:
|
|||
void operator=(const ErrorResult&) = delete;
|
||||
};
|
||||
|
||||
// A class for use when an ErrorResult should just automatically be ignored.
|
||||
class IgnoredErrorResult : public ErrorResult
|
||||
{
|
||||
public:
|
||||
~IgnoredErrorResult()
|
||||
{
|
||||
SuppressException();
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************
|
||||
** Macros for checking results
|
||||
******************************************************************************/
|
||||
|
|
|
@ -83,5 +83,11 @@ MSG_DEF(MSG_NOTIFICATION_PERMISSION_DENIED, 0, JSEXN_TYPEERR, "Permission to sho
|
|||
MSG_DEF(MSG_NOTIFICATION_NO_CONSTRUCTOR_IN_SERVICEWORKER, 0, JSEXN_TYPEERR, "Notification constructor cannot be used in ServiceWorkerGlobalScope. Use registration.showNotification() instead.")
|
||||
MSG_DEF(MSG_INVALID_SCOPE, 2, JSEXN_TYPEERR, "Invalid scope trying to resolve {0} with base URL {1}.")
|
||||
MSG_DEF(MSG_INVALID_KEYFRAME_OFFSETS, 0, JSEXN_TYPEERR, "Keyframes with specified offsets must be in order and all be in the range [0, 1].")
|
||||
MSG_DEF(MSG_ILLEGAL_PROMISE_CONSTRUCTOR, 0, JSEXN_TYPEERR, "Non-constructor value passed to NewPromiseCapability.")
|
||||
MSG_DEF(MSG_PROMISE_CAPABILITY_HAS_SOMETHING_ALREADY, 0, JSEXN_TYPEERR, "GetCapabilitiesExecutor function already invoked with non-undefined values.")
|
||||
MSG_DEF(MSG_PROMISE_RESOLVE_FUNCTION_NOT_CALLABLE, 0, JSEXN_TYPEERR, "A Promise subclass passed a non-callable value as the resolve function.")
|
||||
MSG_DEF(MSG_PROMISE_REJECT_FUNCTION_NOT_CALLABLE, 0, JSEXN_TYPEERR, "A Promise subclass passed a non-callable value as the reject function.")
|
||||
MSG_DEF(MSG_PROMISE_ARG_NOT_ITERABLE, 1, JSEXN_TYPEERR, "{0} is not iterable")
|
||||
MSG_DEF(MSG_IS_NOT_PROMISE, 1, JSEXN_TYPEERR, "{0} is not a Promise")
|
||||
MSG_DEF(MSG_SW_INSTALL_ERROR, 2, JSEXN_TYPEERR, "ServiceWorker script at {0} for scope {1} encountered an error during installation.")
|
||||
MSG_DEF(MSG_SW_SCRIPT_THREW, 2, JSEXN_TYPEERR, "ServiceWorker script at {0} for scope {1} threw an exception during script evaluation.")
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче