Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2016-03-11 16:58:46 +01:00
Родитель 52f665437f e070379821
Коммит 09388646a3
496 изменённых файлов: 9698 добавлений и 4988 удалений

Просмотреть файл

@ -43,9 +43,8 @@ TreeWalker::
mChildFilter(nsIContent::eSkipPlaceholderContent), mFlags(aFlags),
mPhase(eAtStart)
{
MOZ_ASSERT(mFlags & eWalkCache, "This constructor cannot be used for tree creation");
MOZ_ASSERT(aAnchorNode, "No anchor node for the accessible tree walker");
MOZ_ASSERT(mDoc->GetAccessibleOrContainer(aAnchorNode) == mContext,
"Unexpected anchor node was given");
mChildFilter |= mContext->NoXBLKids() ?
nsIContent::eAllButXBL : nsIContent::eAllChildren;
@ -111,7 +110,7 @@ TreeWalker::Seek(nsIContent* aChildNode)
}
Accessible*
TreeWalker::Next()
TreeWalker::Next(nsIContent* aStopNode)
{
if (mStateStack.IsEmpty()) {
if (mPhase == eAtEnd) {
@ -140,38 +139,40 @@ TreeWalker::Next()
dom::AllChildrenIterator* top = &mStateStack[mStateStack.Length() - 1];
while (top) {
if (aStopNode && top->Get() == aStopNode) {
return nullptr;
}
while (nsIContent* childNode = top->GetNextChild()) {
bool skipSubtree = false;
Accessible* child = nullptr;
if (mFlags & eWalkCache) {
child = mDoc->GetAccessible(childNode);
}
else if (mContext->IsAcceptableChild(childNode)) {
child = GetAccService()->
GetOrCreateAccessible(childNode, mContext, &skipSubtree);
}
// Ignore the accessible and its subtree if it was repositioned by means
// of aria-owns.
Accessible* child = AccessibleFor(childNode, mFlags, &skipSubtree);
if (child) {
if (child->IsRelocated()) {
continue;
}
return child;
}
// Walk down into subtree to find accessibles.
// Walk down the subtree if allowed, otherwise check if we have reached
// a stop node.
if (!skipSubtree && childNode->IsElement()) {
top = PushState(childNode, true);
}
else if (childNode == aStopNode) {
return nullptr;
}
}
top = PopState();
}
// If we traversed the whole subtree of the anchor node. Move to next node
// relative anchor node within the context subtree if possible.
if (mFlags != eWalkContextTree)
return Next();
// relative anchor node within the context subtree if asked.
if (mFlags != eWalkContextTree) {
// eWalkCache flag presence indicates that the search is scoped to the
// anchor (no ARIA owns stuff).
if (mFlags & eWalkCache) {
mPhase = eAtEnd;
return nullptr;
}
return Next(aStopNode);
}
nsINode* contextNode = mContext->GetNode();
while (mAnchorNode != contextNode) {
@ -183,7 +184,7 @@ TreeWalker::Next()
top = PushState(parent, true);
if (top->Seek(mAnchorNode)) {
mAnchorNode = parent;
return Next();
return Next(aStopNode);
}
// XXX We really should never get here, it means we're trying to find an
@ -193,7 +194,7 @@ TreeWalker::Next()
mAnchorNode = parent;
}
return Next();
return Next(aStopNode);
}
Accessible*
@ -228,17 +229,10 @@ TreeWalker::Prev()
dom::AllChildrenIterator* top = &mStateStack[mStateStack.Length() - 1];
while (top) {
while (nsIContent* childNode = top->GetPreviousChild()) {
bool skipSubtree = false;
// No accessible creation on the way back.
Accessible* child = mDoc->GetAccessible(childNode);
// Ignore the accessible and its subtree if it was repositioned by means of
// aria-owns.
bool skipSubtree = false;
Accessible* child = AccessibleFor(childNode, eWalkCache, &skipSubtree);
if (child) {
if (child->IsRelocated()) {
continue;
}
return child;
}
@ -278,10 +272,32 @@ TreeWalker::Prev()
return nullptr;
}
Accessible*
TreeWalker::AccessibleFor(nsIContent* aNode, uint32_t aFlags, bool* aSkipSubtree)
{
Accessible* child = nullptr;
if (aFlags & eWalkCache) {
child = mDoc->GetAccessible(aNode);
}
else if (mContext->IsAcceptableChild(aNode)) {
child = GetAccService()->
GetOrCreateAccessible(aNode, mContext, aSkipSubtree);
}
// Ignore the accessible and its subtree if it was repositioned by means
// of aria-owns.
if (child && child->IsRelocated()) {
*aSkipSubtree = true;
return nullptr;
}
return child;
}
dom::AllChildrenIterator*
TreeWalker::PopState()
{
size_t length = mStateStack.Length();
mStateStack.RemoveElementAt(length - 1);
return mStateStack.IsEmpty() ? nullptr : &mStateStack[mStateStack.Length() - 1];
return mStateStack.IsEmpty() ? nullptr : &mStateStack.LastElement();
}

Просмотреть файл

@ -45,7 +45,7 @@ public:
* @param aAnchorNode [in] the node the search will be prepared relative to
* @param aFlags [in] flags (see enum above)
*/
TreeWalker(Accessible* aContext, nsIContent* aAnchorNode, uint32_t aFlags = 0);
TreeWalker(Accessible* aContext, nsIContent* aAnchorNode, uint32_t aFlags = eWalkCache);
~TreeWalker();
@ -62,7 +62,7 @@ public:
* rejected during tree creation then the caller should be unbind it
* from the document.
*/
Accessible* Next();
Accessible* Next(nsIContent* aStopNode = nullptr);
Accessible* Prev();
Accessible* Context() const { return mContext; }
@ -73,6 +73,12 @@ private:
TreeWalker(const TreeWalker&);
TreeWalker& operator =(const TreeWalker&);
/**
* Return an accessible for the given node if any.
*/
Accessible* AccessibleFor(nsIContent* aNode, uint32_t aFlags,
bool* aSkipSubtree);
/**
* Create new state for the given node and push it on top of stack / at bottom
* of stack.

Просмотреть файл

@ -1795,34 +1795,9 @@ DocAccessible::UpdateTreeOnRemoval(Accessible* aContainer, nsIContent* aChildNod
if (child) {
updateFlags |= UpdateTreeInternal(child, false, reorderEvent);
} else {
// aChildNode may not coorespond to a particular accessible, to handle
// this we go through all the children of aContainer. Then if a child
// has aChildNode as an ancestor, or does not have the node for
// aContainer as an ancestor remove that child of aContainer. Note that
// when we are called aChildNode may already have been removed from the DOM
// so we can't expect it to have a parent or what was it's parent to have
// it as a child.
nsINode* containerNode = aContainer->GetNode();
for (uint32_t idx = 0; idx < aContainer->ContentChildCount();) {
Accessible* child = aContainer->ContentChildAt(idx);
// If accessible doesn't have its own content then we assume parent
// will handle its update. If child is DocAccessible then we don't
// handle updating it here either.
if (!child->HasOwnContent() || child->IsDoc()) {
idx++;
continue;
}
nsINode* childNode = child->GetContent();
while (childNode != aChildNode && childNode != containerNode &&
(childNode = childNode->GetParentNode()));
if (childNode != containerNode) {
updateFlags |= UpdateTreeInternal(child, false, reorderEvent);
} else {
idx++;
}
TreeWalker walker(aContainer, aChildNode, TreeWalker::eWalkCache);
while (Accessible* child = walker.Next()) {
updateFlags |= UpdateTreeInternal(child, false, reorderEvent);
}
}

Просмотреть файл

@ -153,6 +153,7 @@
var gQueue = null;
//gA11yEventDumpToConsole = true; // debuging
//enableLogging("tree,verbose");
function doTests()
{

Просмотреть файл

@ -472,6 +472,43 @@
}
}
function removeNotARIAOwnedEl(aContainer, aChild)
{
this.eventSeq = [
new invokerChecker(EVENT_REORDER, aContainer)
];
this.invoke = function removeNotARIAOwnedEl_invoke()
{
dumpTree(aContainer, "before");
var tree = {
SECTION: [
{ TEXT_LEAF: [ ] },
{ GROUPING: [ ] }
]
};
testAccessibleTree(aContainer, tree);
getNode(aContainer).removeChild(getNode(aChild));
}
this.finalCheck = function removeNotARIAOwnedEl_finalCheck()
{
dumpTree(aContainer, "after");
var tree = {
SECTION: [
{ GROUPING: [ ] }
]
};
testAccessibleTree(aContainer, tree);
}
this.getID = function removeNotARIAOwnedEl_getID()
{
return `remove not ARIA owned child`;
}
}
////////////////////////////////////////////////////////////////////////////
// Test
@ -516,6 +553,8 @@
[ "t5_radio", "t5_button" ],
[ "RADIOBUTTON", "PUSHBUTTON", "CHECKBUTTON" ]));
gQueue.push(new removeNotARIAOwnedEl("t6_container", "t6_span"));
gQueue.invoke(); // SimpleTest.finish() will be called in the end
}
@ -563,6 +602,11 @@
<div role="checkbox" id="t5_checkbox"></div>
<div role="radio" id="t5_radio"></div>
</div>
<div id="t6_container" aria-owns="t6_fake">
<span id="t6_span">hey</span>
</div>
<div id="t6_fake" role="group"></div>
</body>
</html>

Просмотреть файл

@ -12,53 +12,22 @@ const { Cc, Ci } = require('chrome');
const { get, set, exists } = Cc['@mozilla.org/process/environment;1'].
getService(Ci.nsIEnvironment);
exports.env = Proxy.create({
// XPCOM does not provides a way to enumerate environment variables, so we
// just don't support enumeration.
getPropertyNames: () => [],
getOwnPropertyNames: () => [],
enumerate: () => [],
keys: () => [],
// We do not support freezing, cause it would make it impossible to set new
// environment variables.
fix: () => undefined,
// We present all environment variables as own properties of this object,
// so we just delegate this call to `getOwnPropertyDescriptor`.
getPropertyDescriptor: function(name) {
return this.getOwnPropertyDescriptor(name);
},
// If environment variable with this name is defined, we generate proprety
// descriptor for it, otherwise fall back to `undefined` so that for consumer
// this property does not exists.
getOwnPropertyDescriptor: function(name) {
return !exists(name) ? undefined : {
value: get(name),
enumerable: false, // Non-enumerable as we don't support enumeration.
configurable: true, // Configurable as it may be deleted.
writable: true // Writable as we do support set.
}
},
// New environment variables can be defined just by defining properties
// on this object.
defineProperty: (name, { value }) => set(name, value),
delete: function(name) {
set(name, null);
exports.env = new Proxy({}, {
deleteProperty(target, property) {
set(property, null);
return true;
},
// We present all properties as own, there for we just delegate to `hasOwn`.
has: function(name) {
return this.hasOwn(name);
get(target, property, receiver) {
return get(property) || undefined;
},
// We do support checks for existence of an environment variable, via `in`
// operator on this object.
hasOwn: name => exists(name),
// On property get / set we do read / write appropriate environment variables,
// please note though, that variables with names of standard object properties
// intentionally (so that this behaves as normal object) can not be
// read / set.
get: (proxy, name) => Object.prototype[name] || get(name) || undefined,
set: (proxy, name, value) => Object.prototype[name] || set(name, value)
has(target, property) {
return exists(property);
},
set(target, property, value, receiver) {
set(property, value);
return true;
}
});

Просмотреть файл

@ -259,22 +259,6 @@ var html = '<input id="input" type="text" /><input id="input3" type="checkbox" /
'<input id="input2" type="checkbox" />';
exports.testStringOverload = createProxyTest(html, function (helper, assert) {
// Proxy - toString error
let originalString = "string";
let p = Proxy.create({
get: function(receiver, name) {
if (name == "binded")
return originalString.toString.bind(originalString);
return originalString[name];
}
});
assert.throws(function () {
p.toString();
},
/toString method called on incompatible Proxy/,
"toString can't be called with this being the proxy");
assert.equal(p.binded(), "string", "but it works if we bind this to the original string");
helper.createWorker(
'new ' + function ContentScriptScope() {
// RightJS is hacking around String.prototype, and do similar thing:

Просмотреть файл

@ -259,22 +259,6 @@ var html = '<input id="input" type="text" /><input id="input3" type="checkbox" /
'<input id="input2" type="checkbox" />';
exports.testStringOverload = createProxyTest(html, function (helper, assert) {
// Proxy - toString error
let originalString = "string";
let p = Proxy.create({
get: function(receiver, name) {
if (name == "binded")
return originalString.toString.bind(originalString);
return originalString[name];
}
});
assert.throws(function () {
p.toString();
},
/toString method called on incompatible Proxy/,
"toString can't be called with this being the proxy");
assert.equal(p.binded(), "string", "but it works if we bind this to the original string");
helper.createWorker(
'new ' + function ContentScriptScope() {
// RightJS is hacking around String.prototype, and do similar thing:

Просмотреть файл

@ -1054,6 +1054,10 @@ pref("dom.apps.reviewer_paths", "/reviewers/,/extension/reviewers/");
// New implementation to unify touch-caret and selection-carets.
pref("layout.accessiblecaret.enabled", true);
// Show the selection bars at the two ends of the selection highlight. Required
// by the spec in bug 921965.
pref("layout.accessiblecaret.bar.enabled", true);
// APZ on real devices supports long tap events.
#ifdef MOZ_WIDGET_GONK
pref("layout.accessiblecaret.use_long_tap_injector", false);

Просмотреть файл

@ -25,7 +25,6 @@ MOZ_NO_SMART_CARDS=1
MOZ_APP_STATIC_INI=1
NSS_DISABLE_DBM=1
MOZ_NO_EV_CERTS=1
MOZ_DISABLE_EXPORT_JS=1
MOZ_WEBSPEECH=1
if test -n "$NIGHTLY_BUILD"; then

Просмотреть файл

@ -33,7 +33,6 @@ MOZ_NO_SMART_CARDS=1
MOZ_APP_STATIC_INI=1
NSS_NO_LIBPKIX=1
NSS_DISABLE_DBM=1
MOZ_DISABLE_EXPORT_JS=1
if test "$OS_TARGET" = "Android"; then
MOZ_CAPTURE=1

Просмотреть файл

@ -219,4 +219,3 @@ extensions.registerSchemaAPI("bookmarks", "bookmarks", (extension, context) => {
},
};
});

Просмотреть файл

@ -108,8 +108,7 @@ var SessionStorageInternal = {
let principal;
try {
let attrs = ChromeUtils.createDefaultOriginAttributes();
attrs.userContextId = aDocShell.userContextId;
let attrs = aDocShell.getOriginAttributes();
let originURI = Services.io.newURI(origin, null, null);
principal = Services.scriptSecurityManager.createCodebasePrincipal(originURI, attrs);
} catch (e) {

Просмотреть файл

@ -6,6 +6,13 @@
"filename": "mozmake.exe"
},
{
"size": 78886322,
"digest": "9c2c40637de27a0852aa1166f2a08159908b23f7a55855c933087c541461bbb2a1ec9e0522df0d2b9da2b2c343b673dbb5a2fa8d30216fe8acee1eb1383336ea",
"algorithm": "sha512",
"filename": "rustc-beta-i686-pc-windows-msvc.tar.bz2",
"unpack": true
},
{
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",
@ -13,9 +20,9 @@
"unpack": true
},
{
"version": "clang 3.9.0/r259916",
"size": 164660139,
"digest": "7db5f16921c10023152e6a7765c6d31dfefc91a8742a14b6279bd253f86a683d8d951b17608aa200978f8cd433ead32e0ae9b53778566d2994e1db7af1df4cc4",
"version": "clang 3.9.0/r262971",
"size": 169861843,
"digest": "8caa5a89aea981b618233d39f01bb934b79b85ee8167104bfa4f07936145df5e8ca5e8e007123d75ccc12d2baa926ffc827b40bf793fa9d4bc2670fa519b0ec0",
"algorithm": "sha512",
"filename": "clang32.tar.bz2",
"unpack": true

Просмотреть файл

@ -6,6 +6,14 @@
"filename": "mozmake.exe"
},
{
"size": 80157273,
"digest": "c4704dcc6774b9f3baaa9313192d26e36bfba2d4380d0518ee7cb89153d9adfe63f228f0ac29848f02948eb1ab7e6624ba71210f0121196d2b54ecebd640d1e6",
"algorithm": "sha512",
"visibility": "public",
"filename": "rustc.tar.bz2",
"unpack": true
},
{
"size": 167175,
"digest": "0b71a936edf5bd70cf274aaa5d7abc8f77fe8e7b5593a208f805cc9436fac646b9c4f0b43c2b10de63ff3da671497d35536077ecbc72dba7f8159a38b580f831",
"algorithm": "sha512",
@ -13,9 +21,9 @@
"unpack": true
},
{
"version": "clang 3.9.0/r259916",
"size": 168551971,
"digest": "af127aba2ed881bad6e83fd162125038f2450f7b6de64efe84d1281052225ec92db6d96d6ade6ac2642f1b00761b3be5725f79c41953dc885a81185097cc81a5",
"version": "clang 3.9.0/r262971",
"size": 173306045,
"digest": "806413640a964dad44c0c6055d2a89a1075730fb6f659ff37341378a14a7dc032e672941765225608b71f6b385ac721ed36bfa04eb38c211b07e2776cb72a0ee",
"algorithm": "sha512",
"filename": "clang64.tar.bz2",
"unpack": true

Просмотреть файл

@ -26,7 +26,6 @@ fi
MOZ_ENABLE_SIGNMAR=1
MOZ_CHROME_FILE_FORMAT=omni
MOZ_DISABLE_EXPORT_JS=1
MOZ_SAFE_BROWSING=1
MOZ_SERVICES_COMMON=1
MOZ_SERVICES_CRYPTO=1

5
browser/extensions/pocket/bootstrap.js поставляемый
Просмотреть файл

@ -108,8 +108,9 @@ PocketAboutPage.prototype = {
Ci.nsIAboutModule.MAKE_UNLINKABLE;
},
newChannel: function(aURI) {
let channel = Services.io.newChannel(this.chromeURL, null, null);
newChannel: function(aURI, aLoadInfo) {
let channel = Services.io.newChannelFromURIWithLoadInfo(this.chromeURL,
aLoadInfo);
channel.originalURI = aURI;
return channel;
},

Просмотреть файл

@ -501,6 +501,8 @@
#endif
@RESPATH@/components/SyncComponents.manifest
@RESPATH@/components/Weave.js
@RESPATH@/components/FxAccountsComponents.manifest
@RESPATH@/components/FxAccountsPush.js
@RESPATH@/components/CaptivePortalDetectComponents.manifest
@RESPATH@/components/captivedetect.js
@RESPATH@/components/servicesComponents.manifest

Просмотреть файл

@ -43,7 +43,7 @@ if test -n "$ENABLE_CLANG_PLUGIN"; then
dnl failure here is benign, so we can ignore it if it happens.
dnl Use tr instead of xargs in order to avoid problems with path separators on Windows.
LLVM_LDFLAGS=`$LLVMCONFIG --system-libs | tr '\n' ' '`
LLVM_LDFLAGS="$LLVM_LDFLAGS `$LLVMCONFIG --ldflags --libs core mc analysis asmparser mcparser bitreader option | tr '\n' ' '`"
LLVM_LDFLAGS="$LLVM_LDFLAGS `$LLVMCONFIG --ldflags --libs core mc analysis asmparser mcparser bitreader option profiledata | tr '\n' ' '`"
if test "${HOST_OS_ARCH}" = "Darwin"; then
CLANG_LDFLAGS="-lclangFrontend -lclangDriver -lclangSerialization"

Просмотреть файл

@ -9,7 +9,7 @@ define([AC_DEFUN], [define($1, [$2])])
dnl AC_ARG_ENABLE(FEATURE, HELP-STRING, IF-TRUE[, IF-FALSE])
dnl We have to ignore the help string due to how help works in autoconf...
AC_DEFUN([AC_ARG_ENABLE],
AC_DEFUN([MOZ_AC_ARG_ENABLE],
[#] Check whether --enable-[$1] or --disable-[$1] was given.
[if test "[${enable_]patsubst([$1], -, _)+set}" = set; then
enableval="[$enable_]patsubst([$1], -, _)"

Просмотреть файл

@ -225,6 +225,18 @@ if test "$GNU_CXX"; then
AC_MSG_ERROR([Your toolchain does not support C++0x/C++11 mode properly. Please upgrade your toolchain])
fi
if test -n "$CLANG_CC"; then
dnl We'd normally just check for the version from CC_VERSION (fed
dnl from __clang_major__ and __clang_minor__), but the clang that
dnl comes with Xcode has a completely different version scheme
dnl despite exposing the version with the same defines.
dnl So instead of a version check, check for one of the C++11
dnl features that was added in clang 3.3.
AC_TRY_COMPILE([], [#if !__has_feature(cxx_inheriting_constructors)
#error inheriting constructors are not supported
#endif],,AC_MSG_ERROR([Only clang/llvm 3.3 or newer supported]))
fi
AC_CACHE_CHECK([whether 64-bits std::atomic requires -latomic],
ac_cv_needs_atomic,
AC_TRY_LINK(
@ -321,6 +333,12 @@ EOF
elif test "$ac_cv_host_cxx0x_headers_bug" = "yes"; then
AC_MSG_ERROR([Your host toolchain does not support C++0x/C++11 mode properly. Please upgrade your toolchain])
fi
if test "$host_compiler" = CLANG; then
AC_TRY_COMPILE([], [#if !__has_feature(cxx_inheriting_constructors)
#error inheriting constructors are not supported
#endif],,AC_MSG_ERROR([Only clang/llvm 3.3 or newer supported]))
fi
CXXFLAGS="$_SAVE_CXXFLAGS"
CPPFLAGS="$_SAVE_CPPFLAGS"
CXX="$_SAVE_CXX"

Просмотреть файл

@ -1,5 +1,5 @@
{
"llvm_revision": "259916",
"llvm_revision": "262971",
"stages": "3",
"build_libcxx": false,
"build_type": "Release",

Просмотреть файл

@ -1,5 +1,5 @@
{
"llvm_revision": "259916",
"llvm_revision": "262971",
"stages": "3",
"build_libcxx": false,
"build_type": "Release",

Просмотреть файл

@ -9,7 +9,10 @@ OS_CXXFLAGS := $(filter-out -W%,$(OS_CXXFLAGS)) -fsyntax-only -Xclang -verify -f
include $(topsrcdir)/config/rules.mk
export:: $(OBJS)
target:: $(OBJS)
# We don't actually build anything.
.PHONY: $(OBJS)
# Don't actually build a library, since we don't actually build objects.
$(LIBRARY): EXPAND_LIBS_GEN=true

Просмотреть файл

@ -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/.
# dummy library name to avoid skipping building the sources here.
Library('clang-plugin-tests')
SOURCES += [
'TestBadImplicitConversionCtor.cpp',
'TestCustomHeap.cpp',

Просмотреть файл

@ -61,6 +61,8 @@ def check_build_environment(help, dist):
)
option(env='OLD_CONFIGURE', nargs=1, help='Path to the old configure script')
option(env='MOZ_CURRENT_PROJECT', nargs=1, help='Current build project')
option(env='MOZCONFIG', nargs=1, help='Mozconfig location')
@ -69,14 +71,32 @@ option(env='MOZCONFIG', nargs=1, help='Mozconfig location')
# Note: the dependency on --help is only there to always read the mozconfig,
# even when --help is passed. Without this dependency, the function wouldn't
# be called when --help is passed, and the mozconfig wouldn't be read.
@depends('MOZ_CURRENT_PROJECT', 'MOZCONFIG', check_build_environment, '--help')
@depends('MOZ_CURRENT_PROJECT', 'MOZCONFIG', 'OLD_CONFIGURE',
check_build_environment, '--help')
@advanced
def mozconfig(current_project, mozconfig, build_env, help):
def mozconfig(current_project, mozconfig, old_configure, build_env, help):
from mozbuild.mozconfig import MozconfigLoader
if not old_configure:
error('The OLD_CONFIGURE environment variable must be set')
# Don't read the mozconfig for the js configure (yay backwards
# compatibility)
if build_env['TOPOBJDIR'].endswith('/js/src'):
# While the long term goal is that js and top-level use the same configure
# and the same overall setup, including the possibility to use mozconfigs,
# figuring out what we want to do wrt mozconfig vs. command line and
# environment variable is not a clear-cut case, and it's more important to
# fix the immediate problem mozconfig causes to js developers by
# "temporarily" returning to the previous behavior of not loading the
# mozconfig for the js configure.
# Separately to the immediate problem for js developers, there is also the
# need to not load a mozconfig when running js configure as a subconfigure.
# Unfortunately, there is no direct way to tell whether the running
# configure is the js configure. The indirect way is to look at the
# OLD_CONFIGURE path, which points to js/src/old-configure.
# I expect we'll have figured things out for mozconfigs well before
# old-configure dies.
if os.path.dirname(os.path.abspath(old_configure[0])).endswith('/js/src'):
return {'path': None}
loader = MozconfigLoader(build_env['TOPSRCDIR'])
@ -88,6 +108,22 @@ def mozconfig(current_project, mozconfig, build_env, help):
return mozconfig
# Hacks related to old-configure
# ==============================
@depends('--help')
def old_configure_assignments(help):
return []
@template
def add_old_configure_assignment(var, value):
@depends(old_configure_assignments)
@advanced
def add_assignment(assignments):
from mozbuild.shellutil import quote
assignments.append('%s=%s' % (var, quote(value)))
option(env='PYTHON', nargs=1, help='Python interpreter')
# Setup python virtualenv
@ -161,6 +197,7 @@ def virtualenv_python(env_python, build_env, mozconfig):
error('Could not determine python site packages directory')
set_config('PYTHON', python)
add_old_configure_assignment('PYTHON', python)
return python
@ -230,6 +267,8 @@ def include_project_configure(project, external_source_dir, build_env, help):
base_dir = build_env['TOPSRCDIR']
if external_source_dir:
set_config('EXTERNAL_SOURCE_DIR', external_source_dir[0])
add_old_configure_assignment('EXTERNAL_SOURCE_DIR',
external_source_dir[0])
base_dir = os.path.join(base_dir, external_source_dir[0])
path = os.path.join(base_dir, project[0], 'moz.configure')
@ -239,8 +278,10 @@ def include_project_configure(project, external_source_dir, build_env, help):
@depends(include_project_configure, check_build_environment, '--help')
def build_project(include_project_configure, build_env, help):
return os.path.dirname(os.path.relpath(include_project_configure,
build_env['TOPSRCDIR']))
ret = os.path.dirname(os.path.relpath(include_project_configure,
build_env['TOPSRCDIR']))
add_old_configure_assignment('MOZ_BUILD_APP', ret)
return ret
# This is temporary until js/src/configure and configure are merged.

Просмотреть файл

@ -57,15 +57,11 @@ def autoconf(mozconfig, autoconf):
return autoconf
option(env='OLD_CONFIGURE', nargs=1, help='Path to the old configure script')
@depends('OLD_CONFIGURE', mozconfig, autoconf, check_build_environment, shell,
virtualenv_python, compile_environment, build_project,
extra_old_configure_args, '--with-external-source-dir')
extra_old_configure_args, old_configure_assignments)
@advanced
def prepare_configure(old_configure, mozconfig, autoconf, build_env, shell,
python, compile_env, build_project,
extra_old_configure_args, external_source_dir):
extra_old_configure_args, old_configure_assignments):
import glob
import itertools
import subprocess
@ -75,9 +71,6 @@ def prepare_configure(old_configure, mozconfig, autoconf, build_env, shell,
from mozbuild.shellutil import quote
if not old_configure:
error('The OLD_CONFIGURE environment variable must be set')
# os.path.abspath in the sandbox will ensure forward slashes on Windows,
# which is actually necessary because this path actually ends up literally
# as $0, and backslashes there breaks autoconf's detection of the source
@ -125,12 +118,8 @@ def prepare_configure(old_configure, mozconfig, autoconf, build_env, shell,
for key in mozconfig[t]['removed'].keys():
print("unset %s" % key, file=out)
print('PYTHON=%s' % quote(python), file=out)
if compile_env:
print('COMPILE_ENVIRONMENT=1', file=out)
print('MOZ_BUILD_APP=%s' % build_project, file=out)
if external_source_dir:
print(external_source_dir.format('EXTERNAL_SOURCE_DIR'), file=out)
for assignment in old_configure_assignments:
print(assignment, file=out)
if extra_old_configure_args:
cmd += extra_old_configure_args
@ -183,7 +172,6 @@ def old_configure_options(*options):
'--enable-dump-painting',
'--enable-elf-hack',
'--enable-eme',
'--enable-export-js',
'--enable-extensions',
'--enable-faststripe',
'--enable-feeds',
@ -247,7 +235,6 @@ def old_configure_options(*options):
'--enable-rust',
'--enable-safe-browsing',
'--enable-sandbox',
'--enable-shared-js',
'--enable-signmar',
'--enable-simulator',
'--enable-skia',

Просмотреть файл

@ -76,3 +76,27 @@ def unique_list(l):
if l not in result:
result.append(i)
return result
# Denotes a deprecated option. Combines option() and @depends:
# @deprecated_option('--option')
# def option(value):
# ...
# @deprecated_option() takes the same arguments as option(), except `help`.
# The function may handle the option like a typical @depends function would,
# but it is recommended it emits a deprecation error message suggesting an
# alternative option to use if there is one.
@template
def deprecated_option(*args, **kwargs):
assert 'help' not in kwargs
kwargs['help'] = 'Deprecated'
opt = option(*args, **kwargs)
def decorator(func):
@depends(opt.option)
def deprecated(value):
if value.origin != 'default':
return func(value)
return deprecated
return decorator

Просмотреть файл

@ -83,7 +83,7 @@ nsJSPrincipals::Destroy(JSPrincipals *jsprin)
#ifdef DEBUG
// Defined here so one can do principals->dump() in the debugger
JS_EXPORT_API(void)
JS_PUBLIC_API(void)
JSPrincipals::dump()
{
if (debugToken == nsJSPrincipals::DEBUG_TOKEN) {

Просмотреть файл

@ -17,6 +17,11 @@
// Silence "warning: #include_next is a GCC extension"
#pragma GCC system_header
// Don't include mozalloc for cstdlib. See bug 1245076.
#ifndef moz_dont_include_mozalloc_for_cstdlib
# define moz_dont_include_mozalloc_for_cstdlib
#endif
#ifndef moz_dont_include_mozalloc_for_${HEADER}
// mozalloc.h wants <new>; break the cycle by always explicitly
// including <new> here. NB: this is a tad sneaky. Sez the gcc docs:
//
@ -25,15 +30,17 @@
// same name as the current file. It simply looks for the file
// named, starting with the directory in the search path after the
// one where the current file was found.
#include_next <new>
# include_next <new>
// See if we're in code that can use mozalloc. NB: this duplicates
// code in nscore.h because nscore.h pulls in prtypes.h, and chromium
// can't build with that being included before base/basictypes.h.
#if !defined(XPCOM_GLUE) && !defined(NS_NO_XPCOM) && !defined(MOZ_NO_MOZALLOC)
# include "mozilla/mozalloc.h"
#else
# error "STL code can only be used with infallible ::operator new()"
# if !defined(XPCOM_GLUE) && !defined(NS_NO_XPCOM) && !defined(MOZ_NO_MOZALLOC)
# include "mozilla/mozalloc.h"
# else
# error "STL code can only be used with infallible ::operator new()"
# endif
#endif
#if defined(DEBUG) && !defined(_GLIBCXX_DEBUG)

Просмотреть файл

@ -22,7 +22,7 @@ const EXPECTED_PROPERTIES = [
].sort();
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_keyframes.html");
yield addTab(URL_ROOT + "doc_keyframes.html");
let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;
let propertiesList = timeline.rootWrapperEl

Просмотреть файл

@ -8,7 +8,7 @@
// them, and that this emits the right events and adds the right classes.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;

Просмотреть файл

@ -8,7 +8,7 @@
// the last known version since new animations were added).
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel, controller} = yield openAnimationInspector();
ok(controller.documentCurrentTime, "The documentCurrentTime getter exists");

Просмотреть файл

@ -11,14 +11,14 @@ const STRINGS_URI = "chrome://devtools/locale/animationinspector.properties";
const L10N = new ViewHelpers.L10N(STRINGS_URI);
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel, window} = yield openAnimationInspector();
let {document} = window;
info("Select node .still and check that the panel is empty");
let stillNode = yield getNodeFront(".still", inspector);
let onUpdated = panel.once(panel.UI_UPDATED_EVENT);
yield selectNode(stillNode, inspector);
yield selectNodeAndWaitForAnimations(stillNode, inspector);
yield onUpdated;
is(panel.animationsTimelineComponent.animations.length, 0,
@ -32,7 +32,7 @@ add_task(function*() {
info("Select the comment text node and check that the panel is empty");
let commentNode = yield inspector.walker.previousSibling(stillNode);
onUpdated = panel.once(panel.UI_UPDATED_EVENT);
yield selectNode(commentNode, inspector);
yield selectNodeAndWaitForAnimations(commentNode, inspector);
yield onUpdated;
is(panel.animationsTimelineComponent.animations.length, 0,

Просмотреть файл

@ -8,7 +8,7 @@
// sets the current time in the timeline.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_keyframes.html");
yield addTab(URL_ROOT + "doc_keyframes.html");
let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;
let {scrubberEl} = timeline;

Просмотреть файл

@ -22,7 +22,7 @@ const EXPECTED_PROPERTIES = [
];
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_keyframes.html");
yield addTab(URL_ROOT + "doc_keyframes.html");
let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;

Просмотреть файл

@ -10,7 +10,7 @@
// different nodes).
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_negative_animation.html");
yield addTab(URL_ROOT + "doc_negative_animation.html");
let {controller, panel} = yield openAnimationInspector();
info("Wait until all animations have been added " +

Просмотреть файл

@ -11,7 +11,7 @@ requestLongerTimeout(2);
// inspector-updated event is emitted *after* the animation panel is ready.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel, controller} = yield openAnimationInspector();
info("Listen for the players-updated, ui-updated and " +
@ -29,7 +29,7 @@ add_task(function*() {
info("Selecting an animated node");
let node = yield getNodeFront(".animated", inspector);
yield selectNode(node, inspector);
yield selectNodeAndWaitForAnimations(node, inspector);
info("Check that all events were received");
// Only assert that the inspector-updated event is last, the order of the

Просмотреть файл

@ -10,26 +10,26 @@ requestLongerTimeout(2);
// AnimationController.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {controller, inspector} = yield openAnimationInspector();
info("Selecting an animated node");
// selectNode waits for the inspector-updated event before resolving, which
// means the controller.PLAYERS_UPDATED_EVENT event has been emitted before
// and players are ready.
yield selectNode(".animated", inspector);
yield selectNodeAndWaitForAnimations(".animated", inspector);
is(controller.animationPlayers.length, 1,
"One AnimationPlayerFront has been created");
info("Selecting a node with mutliple animations");
yield selectNode(".multi", inspector);
yield selectNodeAndWaitForAnimations(".multi", inspector);
is(controller.animationPlayers.length, 2,
"2 AnimationPlayerFronts have been created");
info("Selecting a node with no animations");
yield selectNode(".still", inspector);
yield selectNodeAndWaitForAnimations(".still", inspector);
is(controller.animationPlayers.length, 0,
"There are no more AnimationPlayerFront objects");

Просмотреть файл

@ -16,7 +16,7 @@ add_task(function*() {
]}, resolve);
});
yield addTab(TEST_URL_ROOT + "doc_multiple_animation_types.html");
yield addTab(URL_ROOT + "doc_multiple_animation_types.html");
let {panel} = yield openAnimationInspector();
is(panel.animationsTimelineComponent.animations.length, 3,

Просмотреть файл

@ -9,11 +9,11 @@ requestLongerTimeout(2);
// Test that player widgets display information about target nodes
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Select the simple animated node");
yield selectNode(".animated", inspector);
yield selectNodeAndWaitForAnimations(".animated", inspector);
let targetNodeComponent = panel.animationsTimelineComponent.targetNodes[0];
let {previewer} = targetNodeComponent;

Просмотреть файл

@ -9,11 +9,11 @@ requestLongerTimeout(2);
// Test that the panel content refreshes when new animations are added.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Select a non animated node");
yield selectNode(".still", inspector);
yield selectNodeAndWaitForAnimations(".still", inspector);
assertAnimationsDisplayed(panel, 0);

Просмотреть файл

@ -9,7 +9,7 @@ requestLongerTimeout(2);
// Test that the panel content refreshes when animations are removed.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
yield testRefreshOnRemove(inspector, panel);
@ -17,7 +17,7 @@ add_task(function*() {
function* testRefreshOnRemove(inspector, panel) {
info("Select a animated node");
yield selectNode(".animated", inspector);
yield selectNodeAndWaitForAnimations(".animated", inspector);
assertAnimationsDisplayed(panel, 1);

Просмотреть файл

@ -9,7 +9,7 @@ requestLongerTimeout(2);
// Test that the panel only refreshes when it is visible in the sidebar.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
yield testRefresh(inspector, panel);
@ -17,13 +17,13 @@ add_task(function*() {
function* testRefresh(inspector, panel) {
info("Select a non animated node");
yield selectNode(".still", inspector);
yield selectNodeAndWaitForAnimations(".still", inspector);
info("Switch to the rule-view panel");
inspector.sidebar.select("ruleview");
info("Select the animated node now");
yield selectNode(".animated", inspector);
yield selectNodeAndWaitForAnimations(".animated", inspector);
assertAnimationsDisplayed(panel, 0,
"The panel doesn't show the animation data while inactive");
@ -39,7 +39,7 @@ function* testRefresh(inspector, panel) {
inspector.sidebar.select("ruleview");
info("Select the non animated node again");
yield selectNode(".still", inspector);
yield selectNodeAndWaitForAnimations(".still", inspector);
assertAnimationsDisplayed(panel, 1,
"The panel still shows the previous animation data since it is inactive");

Просмотреть файл

@ -13,12 +13,12 @@ const STRINGS_URI = "chrome://devtools/locale/animationinspector.properties";
const L10N = new ViewHelpers.L10N(STRINGS_URI);
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;
info("Select a test node we know has an animation running on the compositor");
yield selectNode(".animated", inspector);
yield selectNodeAndWaitForAnimations(".animated", inspector);
let animationEl = timeline.animationsEl.querySelector(".animation");
ok(animationEl.classList.contains("fast-track"),
@ -27,7 +27,7 @@ add_task(function*() {
"The animation element has the right tooltip content");
info("Select a node we know doesn't have an animation on the compositor");
yield selectNode(".no-compositor", inspector);
yield selectNodeAndWaitForAnimations(".no-compositor", inspector);
animationEl = timeline.animationsEl.querySelector(".animation");
ok(!animationEl.classList.contains("fast-track"),

Просмотреть файл

@ -10,12 +10,12 @@ requestLongerTimeout(2);
// are created in the panel.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel, controller} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;
info("Selecting the test animated node again");
yield selectNode(".multi", inspector);
yield selectNodeAndWaitForAnimations(".multi", inspector);
is(controller.animationPlayers.length,
timeline.animationsEl.querySelectorAll(".animation").length,

Просмотреть файл

@ -10,12 +10,12 @@ requestLongerTimeout(2);
// selected.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Select node .animated and check that the panel is not empty");
let node = yield getNodeFront(".animated", inspector);
yield selectNode(node, inspector);
yield selectNodeAndWaitForAnimations(node, inspector);
assertAnimationsDisplayed(panel, 1);
});

Просмотреть файл

@ -11,12 +11,12 @@
// browser_animation_toggle_button_toggles_animation.js
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel, inspector, window, controller} = yield openAnimationInspector();
let {toggleAllButtonEl} = panel;
// select a node without animations
yield selectNode(".still", inspector);
yield selectNodeAndWaitForAnimations(".still", inspector);
// ensure the focus is on the animation panel
window.focus();

Просмотреть файл

@ -11,7 +11,7 @@
// is selected, animations will be displayed in the timeline, so the timeline
// play/resume button will be displayed
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel, window} = yield openAnimationInspector();
let {playTimelineButtonEl} = panel;

Просмотреть файл

@ -10,13 +10,13 @@ requestLongerTimeout(2);
// be used to highlight elements in the DOM and select them in the inspector.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {toolbox, inspector, panel} = yield openAnimationInspector();
info("Select the simple animated node");
let onPanelUpdated = panel.once(panel.UI_UPDATED_EVENT);
yield selectNode(".animated", inspector);
yield selectNodeAndWaitForAnimations(".animated", inspector);
yield onPanelUpdated;
let targets = yield waitForAllAnimationTargets(panel);
@ -50,7 +50,7 @@ add_task(function*() {
info("Select the body node in order to have the list of all animations");
onPanelUpdated = panel.once(panel.UI_UPDATED_EVENT);
yield selectNode("body", inspector);
yield selectNodeAndWaitForAnimations("body", inspector);
yield onPanelUpdated;
targets = yield waitForAllAnimationTargets(panel);

Просмотреть файл

@ -10,7 +10,7 @@ requestLongerTimeout(2);
// be used to highlight elements in the DOM and select them in the inspector.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspector();
let targets = panel.animationsTimelineComponent.targetNodes;

Просмотреть файл

@ -11,7 +11,7 @@ requestLongerTimeout(2);
// rewound, and stops when animations are paused.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspector();
let label = panel.timelineCurrentTimeEl;

Просмотреть файл

@ -15,7 +15,7 @@ const {findOptimalTimeInterval, TimeScale} = require("devtools/client/animationi
const TIME_GRADUATION_MIN_SPACING = 40;
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;

Просмотреть файл

@ -17,7 +17,7 @@ requestLongerTimeout(2);
// the timeline does the right thing.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel, inspector} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;
@ -45,7 +45,7 @@ add_task(function*() {
// at the end of the timeline, and the button should remain in play mode.
info("Select an infinite animation, reload the page and wait for the " +
"animation to complete");
yield selectNode(".multi", inspector);
yield selectNodeAndWaitForAnimations(".multi", inspector);
yield reloadTab(inspector);
yield waitForOutOfBoundScrubber(timeline);
@ -64,7 +64,7 @@ add_task(function*() {
// timeline, it should go back to paused mode.
info("Select a finite animation, reload the page and wait for the " +
"animation to complete");
yield selectNode(".negative-delay", inspector);
yield selectNodeAndWaitForAnimations(".negative-delay", inspector);
let onScrubberStopped = waitForScrubberStopped(timeline);
yield reloadTab(inspector);

Просмотреть файл

@ -13,7 +13,7 @@ requestLongerTimeout(2);
// have mixed rates.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel, controller, inspector, toolbox} = yield openAnimationInspector();
@ -34,13 +34,13 @@ add_task(function*() {
checkAllAnimationsRatesChanged(controller, select, .5);
info("Select just one animated node and change its rate only");
yield selectNode(".animated", inspector);
yield selectNodeAndWaitForAnimations(".animated", inspector);
yield changeTimelinePlaybackRate(panel, 2);
checkAllAnimationsRatesChanged(controller, select, 2);
info("Select the <body> again, it should now have mixed-rates animations");
yield selectNode("body", inspector);
yield selectNodeAndWaitForAnimations("body", inspector);
is(select.value, "", "The selected rate is empty");

Просмотреть файл

@ -13,7 +13,7 @@ requestLongerTimeout(2);
// start.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel, controller} = yield openAnimationInspector();
let players = controller.animationPlayers;

Просмотреть файл

@ -9,7 +9,7 @@ requestLongerTimeout(2);
// Check that the timeline does have a scrubber element.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;

Просмотреть файл

@ -13,7 +13,7 @@ requestLongerTimeout(2);
// Finally, also check that the scrubber can be moved using the scrubber handle.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;

Просмотреть файл

@ -12,7 +12,7 @@ requestLongerTimeout(2);
// and measures its position again.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;

Просмотреть файл

@ -12,20 +12,20 @@ requestLongerTimeout(2);
// positive delays.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Selecting a delayed animated node");
yield selectNode(".delayed", inspector);
yield selectNodeAndWaitForAnimations(".delayed", inspector);
let timelineEl = panel.animationsTimelineComponent.rootWrapperEl;
checkDelayAndName(timelineEl, true);
info("Selecting a no-delay animated node");
yield selectNode(".animated", inspector);
yield selectNodeAndWaitForAnimations(".animated", inspector);
checkDelayAndName(timelineEl, false);
info("Selecting a negative-delay animated node");
yield selectNode(".negative-delay", inspector);
yield selectNodeAndWaitForAnimations(".negative-delay", inspector);
checkDelayAndName(timelineEl, true);
});

Просмотреть файл

@ -10,11 +10,11 @@ requestLongerTimeout(2);
// iterations in an animation.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Selecting the test node");
yield selectNode(".delayed", inspector);
yield selectNodeAndWaitForAnimations(".delayed", inspector);
info("Getting the animation element from the panel");
let timelineEl = panel.animationsTimelineComponent.rootWrapperEl;
@ -32,7 +32,7 @@ add_task(function*() {
"The iteration element doesn't have the infinite class");
info("Selecting another test node with an infinite animation");
yield selectNode(".animated", inspector);
yield selectNodeAndWaitForAnimations(".animated", inspector);
info("Getting the animation element from the panel again");
animation = timelineEl.querySelector(".time-block");

Просмотреть файл

@ -10,7 +10,7 @@ requestLongerTimeout(2);
// counts in tooltips.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel, controller} = yield openAnimationInspector();
info("Getting the animation element from the panel");

Просмотреть файл

@ -18,7 +18,7 @@ add_task(function*() {
]}, resolve);
});
yield addTab(TEST_URL_ROOT + "doc_modify_playbackRate.html");
yield addTab(URL_ROOT + "doc_modify_playbackRate.html");
let {panel} = yield openAnimationInspector();

Просмотреть файл

@ -9,7 +9,7 @@ requestLongerTimeout(2);
// Check that the timeline contains the right elements.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspector();
let timeline = panel.animationsTimelineComponent;

Просмотреть файл

@ -9,11 +9,11 @@ requestLongerTimeout(2);
// Test that a page navigation resets the state of the global toggle button.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, panel} = yield openAnimationInspector();
info("Select the non-animated test node");
yield selectNode(".still", inspector);
yield selectNodeAndWaitForAnimations(".still", inspector);
ok(!panel.toggleAllButtonEl.classList.contains("paused"),
"The toggle button is in its running state by default");

Просмотреть файл

@ -12,7 +12,7 @@ requestLongerTimeout(2);
// actor test in /devtools/server/tests/browser/ that does this.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel} = yield openAnimationInspector();
info("Click the toggle button");

Просмотреть файл

@ -12,7 +12,7 @@ requestLongerTimeout(2);
// are animations to be displayed.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {inspector, window} = yield openAnimationInspector();
let doc = window.document;
let toolbar = doc.querySelector("#global-toolbar");
@ -27,7 +27,7 @@ add_task(function*() {
"The timeline toolbar is visible when there are animations");
info("Select a node that has no animations");
yield selectNode(".still", inspector);
yield selectNodeAndWaitForAnimations(".still", inspector);
ok(isNodeVisible(toolbar),
"The toolbar is shown when there are no animations");

Просмотреть файл

@ -10,11 +10,11 @@ requestLongerTimeout(2);
// content, then the widget reflects the changes.
add_task(function*() {
yield addTab(TEST_URL_ROOT + "doc_simple_animation.html");
yield addTab(URL_ROOT + "doc_simple_animation.html");
let {panel, controller, inspector} = yield openAnimationInspector();
info("Select the test node");
yield selectNode(".animated", inspector);
yield selectNodeAndWaitForAnimations(".animated", inspector);
let animation = controller.animationPlayers[0];
yield setStyle(animation, panel, "animationDuration", "5.5s");

Просмотреть файл

@ -5,21 +5,14 @@
"use strict";
var Cu = Components.utils;
const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
const {gDevTools} = require("devtools/client/framework/devtools");
const promise = require("promise");
const {TargetFactory} = require("devtools/client/framework/target");
const {console} = Cu.import("resource://gre/modules/Console.jsm", {});
/* import-globals-from ../../inspector/test/head.js */
// Import the inspector's head.js first (which itself imports shared-head.js).
Services.scriptloader.loadSubScript(
"chrome://mochitests/content/browser/devtools/client/inspector/test/head.js",
this);
const {ViewHelpers} = Cu.import("resource://devtools/client/shared/widgets/ViewHelpers.jsm", {});
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
// All tests are asynchronous
waitForExplicitFinish();
const TEST_URL_ROOT = "http://example.com/browser/devtools/client/animationinspector/test/";
const ROOT_TEST_DIR = getRootDirectory(gTestPath);
const FRAME_SCRIPT_URL = ROOT_TEST_DIR + "doc_frame_script.js";
const FRAME_SCRIPT_URL = CHROME_URL_ROOT + "doc_frame_script.js";
const COMMON_FRAME_SCRIPT_URL = "chrome://devtools/content/shared/frame-script-utils.js";
const TAB_NAME = "animationinspector";
@ -32,20 +25,9 @@ registerCleanupFunction(function*() {
}
});
// Uncomment this pref to dump all devtools emitted events to the console.
// Services.prefs.setBoolPref("devtools.dump.emit", true);
// Uncomment this pref to dump all devtools protocol traffic
// Services.prefs.setBoolPref("devtools.debugger.log", true);
// Set the testing flag on DevToolsUtils and reset it when the test ends
DevToolsUtils.testing = true;
registerCleanupFunction(() => DevToolsUtils.testing = false);
// Clean-up all prefs that might have been changed during a test run
// (safer here because if the test fails, then the pref is never reverted)
registerCleanupFunction(() => {
Services.prefs.clearUserPref("devtools.dump.emit");
Services.prefs.clearUserPref("devtools.debugger.log");
});
@ -54,30 +36,17 @@ registerCleanupFunction(() => {
* @param {String} url The url to be loaded in the new tab
* @return a promise that resolves to the tab object when the url is loaded
*/
function addTab(url) {
info("Adding a new tab with URL: '" + url + "'");
let def = promise.defer();
window.focus();
let tab = window.gBrowser.selectedTab = window.gBrowser.addTab(url);
let browser = tab.linkedBrowser;
info("Loading the helper frame script " + FRAME_SCRIPT_URL);
browser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false);
info("Loading the helper frame script " + COMMON_FRAME_SCRIPT_URL);
browser.messageManager.loadFrameScript(COMMON_FRAME_SCRIPT_URL, false);
browser.addEventListener("load", function onload() {
browser.removeEventListener("load", onload, true);
info("URL '" + url + "' loading complete");
def.resolve(tab);
}, true);
return def.promise;
}
var _addTab = addTab;
addTab = function(url) {
return _addTab(url).then(tab => {
let browser = tab.linkedBrowser;
info("Loading the helper frame script " + FRAME_SCRIPT_URL);
browser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false);
info("Loading the helper frame script " + COMMON_FRAME_SCRIPT_URL);
browser.messageManager.loadFrameScript(COMMON_FRAME_SCRIPT_URL, false);
return tab;
});
};
/**
* Reload the current tab location.
@ -91,20 +60,9 @@ function* reloadTab(inspector) {
yield inspector.once("inspector-updated");
}
/**
* Get the NodeFront for a given css selector, via the protocol
* @param {String} selector
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
* @return {Promise} Resolves to the NodeFront instance
*/
function getNodeFront(selector, {walker}) {
return walker.querySelector(walker.rootNode, selector);
}
/*
* Set the inspector's current selection to a node or to the first match of the
* given css selector.
* given css selector and wait for the animations to be displayed
* @param {String|NodeFront}
* data The node to select
* @param {InspectorPanel} inspector
@ -114,24 +72,18 @@ function getNodeFront(selector, {walker}) {
* Defaults to "test" which instructs the inspector not
* to highlight the node upon selection
* @return {Promise} Resolves when the inspector is updated with the new node
and animations of its subtree are properly displayed.
*/
var selectNode = Task.async(function*(data, inspector, reason = "test") {
info("Selecting the node for '" + data + "'");
let nodeFront = data;
if (!data._form) {
nodeFront = yield getNodeFront(data, inspector);
}
let updated = inspector.once("inspector-updated");
inspector.selection.setNodeFront(nodeFront, reason);
yield updated;
var selectNodeAndWaitForAnimations = Task.async(
function*(data, inspector, reason = "test") {
yield selectNode(data, inspector, reason);
// 99% of the times, selectNode is called to select an animated node, and we
// want to make sure the rest of the test waits for the animations to be
// properly displayed (wait for all target DOM nodes to be previewed).
// Even if there are no animations, this is safe to do.
let {AnimationsPanel} = inspector.sidebar.getWindowForTab(TAB_NAME);
yield waitForAllAnimationTargets(AnimationsPanel);
});
// We want to make sure the rest of the test waits for the animations to
// be properly displayed (wait for all target DOM nodes to be previewed).
let {AnimationsPanel} = inspector.sidebar.getWindowForTab(TAB_NAME);
yield waitForAllAnimationTargets(AnimationsPanel);
}
);
/**
* Check if there are the expected number of animations being displayed in the
@ -176,23 +128,10 @@ var waitForAnimationInspectorReady = Task.async(function*(inspector) {
* @return a promise that resolves when the inspector is ready.
*/
var openAnimationInspector = Task.async(function*() {
let target = TargetFactory.forTab(gBrowser.selectedTab);
info("Opening the toolbox with the inspector selected");
let toolbox = yield gDevTools.showToolbox(target, "inspector");
info("Switching to the animationinspector");
let inspector = toolbox.getPanel("inspector");
let panelReady = waitForAnimationInspectorReady(inspector);
info("Waiting for toolbox focus");
yield waitForToolboxFrameFocus(toolbox);
inspector.sidebar.select(TAB_NAME);
let {inspector, toolbox} = yield openInspectorSidebarTab(TAB_NAME);
info("Waiting for the inspector and sidebar to be ready");
yield panelReady;
yield waitForAnimationInspectorReady(inspector);
let win = inspector.sidebar.getWindowForTab(TAB_NAME);
let {AnimationsController, AnimationsPanel} = win;
@ -227,60 +166,6 @@ var closeAnimationInspector = Task.async(function*() {
yield gDevTools.closeToolbox(target);
});
/**
* Wait for the toolbox frame to receive focus after it loads
* @param {Toolbox} toolbox
* @return a promise that resolves when focus has been received
*/
function waitForToolboxFrameFocus(toolbox) {
info("Making sure that the toolbox's frame is focused");
let def = promise.defer();
let win = toolbox.frame.contentWindow;
waitForFocus(def.resolve, win);
return def.promise;
}
/**
* Checks whether the inspector's sidebar corresponding to the given id already
* exists
* @param {InspectorPanel}
* @param {String}
* @return {Boolean}
*/
function hasSideBarTab(inspector, id) {
return !!inspector.sidebar.getWindowForTab(id);
}
/**
* Wait for eventName on target.
* @param {Object} target An observable object that either supports on/off or
* addEventListener/removeEventListener
* @param {String} eventName
* @param {Boolean} useCapture Optional, for add/removeEventListener
* @return A promise that resolves when the event has been handled
*/
function once(target, eventName, useCapture = false) {
info("Waiting for event: '" + eventName + "' on " + target + ".");
let deferred = promise.defer();
for (let [add, remove] of [
["addEventListener", "removeEventListener"],
["addListener", "removeListener"],
["on", "off"]
]) {
if ((add in target) && (remove in target)) {
target[add](eventName, function onEvent(...aArgs) {
target[remove](eventName, onEvent, useCapture);
deferred.resolve.apply(deferred, aArgs);
}, useCapture);
break;
}
}
return deferred.promise;
}
/**
* Wait for a content -> chrome message on the message manager (the window
* messagemanager is used).

Двоичный файл не отображается.

Просмотреть файл

@ -287,14 +287,14 @@ promise_test(function(t) {
promise_test(function(t) {
var div = addDiv(t);
var animation = div.animate({ opacity: [ 0, 1 ] }, 100000);
var animation = div.animate({ opacity: [ 0, 1 ] }, 100000); // 100s
return animation.ready.then(t.step_func(function() {
assert_equals(animation.isRunningOnCompositor, omtaEnabled,
'Animation reports that it is running on the compositor');
animation.currentTime = 50000;
animation.effect.timing.duration = 10000;
animation.currentTime = 50000; // 50s
animation.effect.timing.duration = 10000; // 10s
assert_equals(animation.isRunningOnCompositor, false,
'Animation reports that it is NOT running on the compositor'
@ -305,19 +305,19 @@ promise_test(function(t) {
promise_test(function(t) {
var div = addDiv(t);
var animation = div.animate({ opacity: [ 0, 1 ] }, 10000);
var animation = div.animate({ opacity: [ 0, 1 ] }, 100000); // 100s
return animation.ready.then(t.step_func(function() {
assert_equals(animation.isRunningOnCompositor, omtaEnabled,
'Animation reports that it is running on the compositor');
animation.currentTime = 50000;
animation.currentTime = 500000; // 500s
assert_equals(animation.isRunningOnCompositor, false,
'Animation reports that it is NOT running on the compositor'
+ ' when finished');
animation.effect.timing.duration = 100000;
animation.effect.timing.duration = 1000000; // 1000s
return waitForFrame();
})).then(t.step_func(function() {
assert_equals(animation.isRunningOnCompositor, omtaEnabled,
@ -329,19 +329,19 @@ promise_test(function(t) {
promise_test(function(t) {
var div = addDiv(t);
var animation = div.animate({ opacity: [ 0, 1 ] }, 10000);
var animation = div.animate({ opacity: [ 0, 1 ] }, 100000); // 100s
return animation.ready.then(t.step_func(function() {
assert_equals(animation.isRunningOnCompositor, omtaEnabled,
'Animation reports that it is running on the compositor');
animation.effect.timing.endDelay = 10000;
animation.effect.timing.endDelay = 100000; // 100s
assert_equals(animation.isRunningOnCompositor, omtaEnabled,
'Animation reports that it is running on the compositor'
+ ' when endDelay is changed');
animation.currentTime = 11000;
animation.currentTime = 110000; // 110s
return waitForFrame();
})).then(t.step_func(function() {
assert_equals(animation.isRunningOnCompositor, false,
@ -353,13 +353,13 @@ promise_test(function(t) {
promise_test(function(t) {
var div = addDiv(t);
var animation = div.animate({ opacity: [ 0, 1 ] }, 10000);
var animation = div.animate({ opacity: [ 0, 1 ] }, 100000); // 100s
return animation.ready.then(t.step_func(function() {
assert_equals(animation.isRunningOnCompositor, omtaEnabled,
'Animation reports that it is running on the compositor');
animation.effect.timing.endDelay = -20000;
animation.effect.timing.endDelay = -200000; // -200s
return waitForFrame();
})).then(t.step_func(function() {
assert_equals(animation.isRunningOnCompositor, false,
@ -371,19 +371,19 @@ promise_test(function(t) {
promise_test(function(t) {
var div = addDiv(t);
var animation = div.animate({ opacity: [ 0, 1 ] }, 10000);
var animation = div.animate({ opacity: [ 0, 1 ] }, 100000); // 100s
return animation.ready.then(t.step_func(function() {
assert_equals(animation.isRunningOnCompositor, omtaEnabled,
'Animation reports that it is running on the compositor');
animation.effect.timing.endDelay = -5000;
animation.effect.timing.endDelay = -50000; // 50s
return waitForFrame();
})).then(t.step_func(function() {
assert_equals(animation.isRunningOnCompositor, omtaEnabled,
'Animation reports that it is running on the compositor'
+ ' when endTime is positive and endDelay is negative');
animation.currentTime = 6000;
animation.currentTime = 60000; // 60s
return waitForFrame();
})).then(t.step_func(function() {
assert_equals(animation.isRunningOnCompositor, false,
@ -391,7 +391,7 @@ promise_test(function(t) {
+ ' when currentTime is after endTime');
}));
}, 'animation is NOT running on compositor' +
'when endTime is positive and endDelay is negative');
' when endTime is positive and endDelay is negative');
</script>
</script>

Просмотреть файл

@ -814,7 +814,7 @@ nsDOMWindowUtils::SendWheelEvent(float aX,
wheelEvent.refPoint = nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
widget->DispatchAPZAwareEvent(&wheelEvent);
widget->DispatchInputEvent(&wheelEvent);
if (widget->AsyncPanZoomEnabled()) {
// Computing overflow deltas is not compatible with APZ, so if APZ is

Просмотреть файл

@ -7535,20 +7535,20 @@ nsGlobalWindow::MozRequestOverfill(OverfillCallback& aCallback,
}
void
nsGlobalWindow::ClearTimeout(int32_t aHandle, ErrorResult& aError)
nsGlobalWindow::ClearTimeout(int32_t aHandle)
{
MOZ_RELEASE_ASSERT(IsInnerWindow());
if (aHandle > 0) {
ClearTimeoutOrInterval(aHandle, aError);
ClearTimeoutOrInterval(aHandle);
}
}
void
nsGlobalWindow::ClearInterval(int32_t aHandle, ErrorResult& aError)
nsGlobalWindow::ClearInterval(int32_t aHandle)
{
if (aHandle > 0) {
ClearTimeoutOrInterval(aHandle, aError);
ClearTimeoutOrInterval(aHandle);
}
}
@ -11911,6 +11911,7 @@ nsGlobalWindow::RunTimeoutHandler(nsTimeout* aTimeout,
reason = "setTimeout handler";
}
bool abortIntervalHandler = false;
nsCOMPtr<nsIScriptTimeoutHandler> handler(timeout->mScriptHandler);
RefPtr<Function> callback = handler->GetCallback();
if (!callback) {
@ -11930,17 +11931,35 @@ nsGlobalWindow::RunTimeoutHandler(nsTimeout* aTimeout,
options.setFileAndLine(filename, lineNo)
.setVersion(JSVERSION_DEFAULT);
JS::Rooted<JSObject*> global(aes.cx(), FastGetGlobalJSObject());
nsJSUtils::EvaluateString(aes.cx(), nsDependentString(script),
global, options);
nsresult rv =
nsJSUtils::EvaluateString(aes.cx(), nsDependentString(script),
global, options);
if (rv == NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE) {
abortIntervalHandler = true;
}
} else {
// Hold strong ref to ourselves while we call the callback.
nsCOMPtr<nsISupports> me(static_cast<nsIDOMWindow *>(this));
ErrorResult ignored;
ErrorResult rv;
JS::Rooted<JS::Value> ignoredVal(CycleCollectedJSRuntime::Get()->Runtime());
callback->Call(me, handler->GetArgs(), &ignoredVal, ignored, reason);
ignored.SuppressException();
callback->Call(me, handler->GetArgs(), &ignoredVal, rv, reason);
if (rv.IsUncatchableException()) {
abortIntervalHandler = true;
}
rv.SuppressException();
}
// If we received an uncatchable exception, do not schedule the timeout again.
// This allows the slow script dialog to break easy DoS attacks like
// setInterval(function() { while(1); }, 100);
if (abortIntervalHandler) {
// If it wasn't an interval timer to begin with, this does nothing. If it
// was, we'll treat it as a timeout that we just ran and discard it when
// we return.
timeout->mIsInterval = false;
}
// We ignore any failures from calling EvaluateString() on the context or
// Call() on a Function here since we're in a loop
// where we're likely to be running timeouts whose OS timers
@ -12216,7 +12235,7 @@ nsGlobalWindow::RunTimeout(nsTimeout *aTimeout)
}
void
nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID, ErrorResult& aError)
nsGlobalWindow::ClearTimeoutOrInterval(int32_t aTimerID)
{
MOZ_RELEASE_ASSERT(IsInnerWindow());

Просмотреть файл

@ -971,7 +971,7 @@ public:
int32_t aTimeout,
const mozilla::dom::Sequence<JS::Value>& /* unused */,
mozilla::ErrorResult& aError);
void ClearTimeout(int32_t aHandle, mozilla::ErrorResult& aError);
void ClearTimeout(int32_t aHandle);
int32_t SetInterval(JSContext* aCx, mozilla::dom::Function& aFunction,
const mozilla::dom::Optional<int32_t>& aTimeout,
const mozilla::dom::Sequence<JS::Value>& aArguments,
@ -980,7 +980,7 @@ public:
const mozilla::dom::Optional<int32_t>& aTimeout,
const mozilla::dom::Sequence<JS::Value>& /* unused */,
mozilla::ErrorResult& aError);
void ClearInterval(int32_t aHandle, mozilla::ErrorResult& aError);
void ClearInterval(int32_t aHandle);
void Atob(const nsAString& aAsciiBase64String, nsAString& aBinaryData,
mozilla::ErrorResult& aError);
void Btoa(const nsAString& aBinaryData, nsAString& aAsciiBase64String,
@ -1435,8 +1435,7 @@ public:
int32_t SetTimeoutOrInterval(JSContext* aCx, const nsAString& aHandler,
int32_t aTimeout, bool aIsInterval,
mozilla::ErrorResult& aError);
void ClearTimeoutOrInterval(int32_t aTimerID,
mozilla::ErrorResult& aError);
void ClearTimeoutOrInterval(int32_t aTimerID);
// JS specific timeout functions (JS args grabbed from context).
nsresult ResetTimersForNonBackgroundWindow();

Просмотреть файл

@ -233,7 +233,12 @@ nsJSUtils::EvaluateString(JSContext* aCx,
}
if (!ok) {
rv = NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW;
if (JS_IsExceptionPending(aCx)) {
rv = NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW;
} else {
rv = NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE;
}
if (!aCompileOptions.noScriptRval) {
aRetValue.setUndefined();
}

Просмотреть файл

@ -798,6 +798,8 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' #CLICK_TO_PLAY
skip-if = toolkit == 'android'
[test_reentrant_flush.html]
skip-if = toolkit == 'android'
[test_setInterval_uncatchable_exception.html]
skip-if = debug == false
[test_sync_xhr_timer.xhtml]
skip-if = toolkit == 'android'
[test_text_wholeText.html]

Просмотреть файл

@ -0,0 +1,55 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1252268
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1252268</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1252268">Mozilla Bug 1252268</a>
<script type="text/javascript">
function go() {
SimpleTest.requestFlakyTimeout("I'm smarter than the test harness");
var ranOnce = false;
var finished = false;
var interval = setInterval(function () {
if (ranOnce) {
ok(false, "Don't execute me again!");
clearInterval(interval);
if (!finished) {
finished = true;
SimpleTest.finish();
}
} else {
ranOnce = true;
ok(true, "Ran the first time");
try {
TestFunctions.throwUncatchableException();
ok(false, "How did we get here!");
} catch (e) {
ok(false, "How did we get here!?");
}
}
}, 100);
setTimeout(function() {
if (!finished) {
finished = true;
SimpleTest.finish();
}
}, 1000);
}
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({set: [['dom.expose_test_interfaces', true]]}, go);
</script>
</body>
</html>

Просмотреть файл

@ -476,9 +476,8 @@ ErrorResult::SetPendingException(JSContext* cx)
return;
}
if (IsJSContextException()) {
// Whatever we need to throw is on the JSContext already. We
// can't assert that there is a pending exception on it, though,
// because in the uncatchable exception case there won't be one.
// Whatever we need to throw is on the JSContext already.
MOZ_ASSERT(JS_IsExceptionPending(cx));
mResult = NS_OK;
return;
}
@ -513,6 +512,16 @@ ErrorResult::StealExceptionFromJSContext(JSContext* cx)
JS_ClearPendingException(cx);
}
void
ErrorResult::NoteJSContextException(JSContext* aCx)
{
if (JS_IsExceptionPending(aCx)) {
mResult = NS_ERROR_DOM_EXCEPTION_ON_JSCONTEXT;
} else {
mResult = NS_ERROR_UNCATCHABLE_EXCEPTION;
}
}
namespace dom {
bool

Просмотреть файл

@ -1272,6 +1272,10 @@ DOMInterfaces = {
'concrete': False,
},
'TestFunctions': {
'wrapperCache': False
},
'Text': {
# Total hack to allow binding code to realize that nsTextNode can
# in fact be cast to Text.

Просмотреть файл

@ -297,6 +297,12 @@ CallbackObject::CallSetup::~CallSetup()
if (saved) {
JS_RestoreFrameChain(mCx);
}
if (mErrorResult.IsJSContextException()) {
// XXXkhuey bug 1117269.
// This isn't true anymore ... so throw something else.
mErrorResult.Throw(NS_ERROR_UNEXPECTED);
}
}
}

Просмотреть файл

@ -15183,7 +15183,7 @@ class CallbackMethod(CallbackMember):
$*{declThis}
if (${callGuard}!JS::Call(cx, ${thisVal}, callable,
${args}, &rval)) {
aRv.Throw(NS_ERROR_UNEXPECTED);
aRv.NoteJSContextException(cx);
return${errorReturn};
}
""",

Просмотреть файл

@ -235,9 +235,9 @@ public:
// Flag on the ErrorResult that whatever needs throwing has been
// thrown on the JSContext already and we should not mess with it.
void NoteJSContextException() {
mResult = NS_ERROR_DOM_EXCEPTION_ON_JSCONTEXT;
}
// If nothing was thrown, this becomes an uncatchable exception.
void NoteJSContextException(JSContext* aCx);
// Check whether the ErrorResult says to just throw whatever is on
// the JSContext already.
bool IsJSContextException() {

Просмотреть файл

@ -62,6 +62,7 @@ MSG_DEF(MSG_MISSING_REQUIRED_DICTIONARY_MEMBER, 1, JSEXN_TYPEERR, "Missing requi
MSG_DEF(MSG_INVALID_REQUEST_METHOD, 1, JSEXN_TYPEERR, "Invalid request method {0}.")
MSG_DEF(MSG_INVALID_REQUEST_MODE, 1, JSEXN_TYPEERR, "Invalid request mode {0}.")
MSG_DEF(MSG_INVALID_REFERRER_URL, 1, JSEXN_TYPEERR, "Invalid referrer URL {0}.")
MSG_DEF(MSG_CROSS_ORIGIN_REFERRER_URL, 2, JSEXN_TYPEERR, "Referrer URL {0} cannot be cross-origin to the entry settings object ({1}).")
MSG_DEF(MSG_FETCH_BODY_CONSUMED_ERROR, 0, JSEXN_TYPEERR, "Body has already been consumed.")
MSG_DEF(MSG_RESPONSE_INVALID_STATUSTEXT_ERROR, 0, JSEXN_TYPEERR, "Response statusText may not contain newline or carriage return.")
MSG_DEF(MSG_FETCH_FAILED, 0, JSEXN_TYPEERR, "NetworkError when attempting to fetch resource.")

Просмотреть файл

@ -100,6 +100,7 @@ SOURCES += [
# them are only run in debug mode.
if CONFIG['MOZ_DEBUG']:
EXPORTS.mozilla.dom += [
"test/TestFunctions.h",
"test/TestInterfaceIterableDouble.h",
"test/TestInterfaceIterableSingle.h",
"test/TestInterfaceMaplike.h",
@ -108,6 +109,7 @@ if CONFIG['MOZ_DEBUG']:
"test/TestInterfaceSetlikeNode.h"
]
UNIFIED_SOURCES += [
"test/TestFunctions.cpp",
"test/TestInterfaceIterableDouble.cpp",
"test/TestInterfaceIterableSingle.cpp",
"test/TestInterfaceMaplike.cpp",

Просмотреть файл

@ -0,0 +1,20 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/TestFunctions.h"
namespace mozilla {
namespace dom {
/* static */ void
TestFunctions::ThrowUncatchableException(GlobalObject& aGlobal,
ErrorResult& aRv)
{
aRv.ThrowUncatchableException();
}
}
}

Просмотреть файл

@ -0,0 +1,26 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_TestFunctions_h
#define mozilla_dom_TestFunctions_h
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/NonRefcountedDOMObject.h"
namespace mozilla {
namespace dom {
class TestFunctions : public NonRefcountedDOMObject {
public:
static void
ThrowUncatchableException(GlobalObject& aGlobal, ErrorResult& aRv);
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_TestFunctions_h

Просмотреть файл

@ -10,7 +10,7 @@
#include "BluetoothService.h"
#include "BluetoothSocket.h"
#include "BluetoothUtils.h"
#include "BluetoothUuid.h"
#include "BluetoothUuidHelper.h"
#include "ObexBase.h"
#include "mozilla/dom/BluetoothMapParametersBinding.h"

Просмотреть файл

@ -10,7 +10,7 @@
#include "BluetoothService.h"
#include "BluetoothSocket.h"
#include "BluetoothUtils.h"
#include "BluetoothUuid.h"
#include "BluetoothUuidHelper.h"
#include "ObexBase.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"

Просмотреть файл

@ -10,7 +10,7 @@
#include "BluetoothService.h"
#include "BluetoothSocket.h"
#include "BluetoothUtils.h"
#include "BluetoothUuid.h"
#include "BluetoothUuidHelper.h"
#include "mozilla/dom/BluetoothPbapParametersBinding.h"
#include "mozilla/Endian.h"

Просмотреть файл

@ -29,7 +29,7 @@
#include "BluetoothProfileController.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothUtils.h"
#include "BluetoothUuid.h"
#include "BluetoothUuidHelper.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/ipc/SocketBase.h"
#include "mozilla/StaticMutex.h"

Просмотреть файл

@ -28,7 +28,7 @@
#include "BluetoothReplyRunnable.h"
#include "BluetoothUnixSocketConnector.h"
#include "BluetoothUtils.h"
#include "BluetoothUuid.h"
#include "BluetoothUuidHelper.h"
#include <cstdio>
#include <dbus/dbus.h>

Просмотреть файл

@ -13,7 +13,7 @@
#include "BluetoothService.h"
#include "BluetoothSocket.h"
#include "BluetoothUtils.h"
#include "BluetoothUuid.h"
#include "BluetoothUuidHelper.h"
#include "jsapi.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"

Просмотреть файл

@ -10,7 +10,7 @@
#include "BluetoothService.h"
#include "BluetoothSocket.h"
#include "BluetoothUtils.h"
#include "BluetoothUuid.h"
#include "BluetoothUuidHelper.h"
#include "ObexBase.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"

Просмотреть файл

@ -199,11 +199,19 @@ BluetoothProfileController::SetupProfiles(bool aAssignServiceClass)
}
// Rendering bit should be set if remote device supports A2DP.
// A device which supports AVRCP should claim that it's a peripheral and it's
// a remote control.
if (hasRendering || (isPeripheral && isRemoteControl)) {
if (hasRendering) {
AddProfile(BluetoothA2dpManager::Get());
AddProfile(BluetoothAvrcpManager::Get()); // register after A2DP
}
// A remote control may either support HID or AVRCP since class of device
// value are the same. So we can only differentiate between AVRCP and HID
// by using hasRendering bit.
if ((isPeripheral && isRemoteControl)) {
if (hasRendering) {
AddProfile(BluetoothAvrcpManager::Get());
} else {
AddProfile(BluetoothHidManager::Get());
}
}
// A device which supports HID should claim that it's a peripheral and it's

Просмотреть файл

@ -7,7 +7,7 @@
#ifndef mozilla_dom_bluetooth_BluetoothProfileController_h
#define mozilla_dom_bluetooth_BluetoothProfileController_h
#include "BluetoothUuid.h"
#include "BluetoothUuidHelper.h"
#include "nsISupportsImpl.h"
#include "nsAutoPtr.h"
#include "nsITimer.h"

Просмотреть файл

@ -4,7 +4,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "BluetoothUuid.h"
#include "BluetoothUuidHelper.h"
#include "BluetoothA2dpManager.h"
#include "BluetoothAvrcpManager.h"

Просмотреть файл

@ -4,8 +4,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_bluetooth_BluetoothUuid_h
#define mozilla_dom_bluetooth_BluetoothUuid_h
#ifndef mozilla_dom_bluetooth_BluetoothUuidHelper_h
#define mozilla_dom_bluetooth_BluetoothUuidHelper_h
#include "BluetoothCommon.h"
@ -51,4 +51,4 @@ enum BluetoothReservedChannels {
END_BLUETOOTH_NAMESPACE
#endif // mozilla_dom_bluetooth_BluetoothUuid_h
#endif // mozilla_dom_bluetooth_BluetoothUuidHelper_h

Просмотреть файл

@ -23,7 +23,7 @@ if CONFIG['MOZ_B2G_BT']:
'common/BluetoothReplyRunnable.cpp',
'common/BluetoothService.cpp',
'common/BluetoothUtils.cpp',
'common/BluetoothUuid.cpp',
'common/BluetoothUuidHelper.cpp',
'common/ObexBase.cpp',
'common/webapi/BluetoothAdapter.cpp',
'common/webapi/BluetoothClassOfDevice.cpp',

Просмотреть файл

@ -5356,7 +5356,7 @@ void
CanvasRenderingContext2D::PutImageData(ImageData& aImageData, double aDx,
double aDy, ErrorResult& aError)
{
dom::Uint8ClampedArray arr;
RootedTypedArray<Uint8ClampedArray> arr(nsContentUtils::RootingCxForThread());
DebugOnly<bool> inited = arr.Init(aImageData.GetDataObject());
MOZ_ASSERT(inited);
@ -5372,7 +5372,7 @@ CanvasRenderingContext2D::PutImageData(ImageData& aImageData, double aDx,
double aDirtyHeight,
ErrorResult& aError)
{
dom::Uint8ClampedArray arr;
RootedTypedArray<Uint8ClampedArray> arr(nsContentUtils::RootingCxForThread());
DebugOnly<bool> inited = arr.Init(aImageData.GetDataObject());
MOZ_ASSERT(inited);

Просмотреть файл

@ -567,16 +567,6 @@ protected:
*/
static uint32_t sNumLivingContexts;
/**
* Lookup table used to speed up GetImageData().
*/
static uint8_t (*sUnpremultiplyTable)[256];
/**
* Lookup table used to speed up PutImageData().
*/
static uint8_t (*sPremultiplyTable)[256];
static mozilla::gfx::DrawTarget* sErrorTarget;
// Some helpers. Doesn't modify a color on failure.

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше