mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
9eb45808ae
2
CLOBBER
2
CLOBBER
@ -22,4 +22,4 @@
|
||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
Bug 1186060 - Switch Windows compiler from VS2013 to VS2015
|
||||
no Bug - touch clobber to fix Bustage
|
||||
|
@ -235,6 +235,7 @@ EventTree::Process()
|
||||
if (mFireReorder) {
|
||||
MOZ_ASSERT(mContainer);
|
||||
nsEventShell::FireEvent(nsIAccessibleEvent::EVENT_REORDER, mContainer);
|
||||
mContainer->Document()->MaybeNotifyOfValueChange(mContainer);
|
||||
}
|
||||
|
||||
mDependentEvents.Clear();
|
||||
|
@ -702,7 +702,7 @@ TextAttrsMgr::TextDecorValue::
|
||||
bool isForegroundColor = false;
|
||||
textReset->GetDecorationColor(mColor, isForegroundColor);
|
||||
if (isForegroundColor)
|
||||
mColor = aFrame->StyleColor()->mColor;
|
||||
mColor = aFrame->StyleContext()->GetTextFillColor();
|
||||
|
||||
mLine = textReset->mTextDecorationLine &
|
||||
(NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE |
|
||||
|
@ -138,7 +138,7 @@ nsCoreUtils::DispatchMouseEvent(EventMessage aMessage, int32_t aX, int32_t aY,
|
||||
WidgetMouseEvent event(true, aMessage, aRootWidget,
|
||||
WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal);
|
||||
|
||||
event.refPoint = LayoutDeviceIntPoint(aX, aY);
|
||||
event.mRefPoint = LayoutDeviceIntPoint(aX, aY);
|
||||
|
||||
event.clickCount = 1;
|
||||
event.button = WidgetMouseEvent::eLeftButton;
|
||||
|
@ -539,7 +539,7 @@ Accessible::ChildAtPoint(int32_t aX, int32_t aY,
|
||||
|
||||
WidgetMouseEvent dummyEvent(true, eMouseMove, rootWidget,
|
||||
WidgetMouseEvent::eSynthesized);
|
||||
dummyEvent.refPoint = LayoutDeviceIntPoint(aX - rootRect.x, aY - rootRect.y);
|
||||
dummyEvent.mRefPoint = LayoutDeviceIntPoint(aX - rootRect.x, aY - rootRect.y);
|
||||
|
||||
nsIFrame* popupFrame = nsLayoutUtils::
|
||||
GetPopupFrameForEventCoordinates(accDocument->PresContext()->GetRootPresContext(),
|
||||
|
@ -1856,8 +1856,6 @@ DocAccessible::FireEventsOnInsertion(Accessible* aContainer,
|
||||
}
|
||||
while ((ancestor = ancestor->Parent()));
|
||||
}
|
||||
|
||||
MaybeNotifyOfValueChange(aContainer);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1879,12 +1877,10 @@ DocAccessible::UpdateTreeOnRemoval(Accessible* aContainer, nsIContent* aChildNod
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t updateFlags = eNoAccessible;
|
||||
TreeMutation mt(aContainer);
|
||||
|
||||
if (child) {
|
||||
mt.BeforeRemoval(child);
|
||||
updateFlags |= UpdateTreeInternal(child, false);
|
||||
UpdateTreeInternal(child, false);
|
||||
}
|
||||
else {
|
||||
TreeWalker walker(aContainer, aChildNode, TreeWalker::eWalkCache);
|
||||
@ -1892,17 +1888,12 @@ DocAccessible::UpdateTreeOnRemoval(Accessible* aContainer, nsIContent* aChildNod
|
||||
if (child) {
|
||||
do {
|
||||
mt.BeforeRemoval(child);
|
||||
updateFlags |= UpdateTreeInternal(child, false);
|
||||
UpdateTreeInternal(child, false);
|
||||
}
|
||||
while ((child = walker.Next()));
|
||||
}
|
||||
}
|
||||
mt.Done();
|
||||
|
||||
// Content insertion/removal is not cause of accessible tree change.
|
||||
if (updateFlags != eNoAccessible) {
|
||||
MaybeNotifyOfValueChange(aContainer);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@ -2172,9 +2163,7 @@ DocAccessible::MoveChild(Accessible* aChild, Accessible* aNewParent,
|
||||
|
||||
if (curParent == aNewParent) {
|
||||
MOZ_ASSERT(aChild->IndexInParent() != aIdxInParent, "No move case");
|
||||
|
||||
curParent->MoveChild(aIdxInParent, aChild);
|
||||
MaybeNotifyOfValueChange(curParent);
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
logging::TreeInfo("move child: parent tree after",
|
||||
@ -2192,8 +2181,6 @@ DocAccessible::MoveChild(Accessible* aChild, Accessible* aNewParent,
|
||||
curParent->RemoveChild(aChild);
|
||||
rmut.Done();
|
||||
|
||||
MaybeNotifyOfValueChange(curParent);
|
||||
|
||||
// No insertion point for the child.
|
||||
if (aIdxInParent == -1) {
|
||||
return true;
|
||||
@ -2204,8 +2191,6 @@ DocAccessible::MoveChild(Accessible* aChild, Accessible* aNewParent,
|
||||
imut.AfterInsertion(aChild);
|
||||
imut.Done();
|
||||
|
||||
MaybeNotifyOfValueChange(aNewParent);
|
||||
|
||||
#ifdef A11Y_LOG
|
||||
logging::TreeInfo("move child: old parent tree after",
|
||||
logging::eVerbose, curParent);
|
||||
|
@ -1845,53 +1845,6 @@ DocAccessibleChild::RecvTakeFocus(const uint64_t& aID)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvEmbeddedChildCount(const uint64_t& aID,
|
||||
uint32_t* aCount)
|
||||
{
|
||||
*aCount = 0;
|
||||
|
||||
Accessible* acc = IdToAccessible(aID);
|
||||
if (!acc) {
|
||||
return true;
|
||||
}
|
||||
|
||||
*aCount = acc->EmbeddedChildCount();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvIndexOfEmbeddedChild(const uint64_t& aID,
|
||||
const uint64_t& aChildID,
|
||||
uint32_t* aChildIdx)
|
||||
{
|
||||
*aChildIdx = 0;
|
||||
|
||||
Accessible* parent = IdToAccessible(aID);
|
||||
Accessible* child = IdToAccessible(aChildID);
|
||||
if (!parent || !child)
|
||||
return true;
|
||||
|
||||
*aChildIdx = parent->GetIndexOfEmbeddedChild(child);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvEmbeddedChildAt(const uint64_t& aID,
|
||||
const uint32_t& aIdx,
|
||||
uint64_t* aChildID)
|
||||
{
|
||||
*aChildID = 0;
|
||||
|
||||
Accessible* acc = IdToAccessible(aID);
|
||||
if (!acc)
|
||||
return true;
|
||||
|
||||
*aChildID = reinterpret_cast<uintptr_t>(acc->GetEmbeddedChildAt(aIdx));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DocAccessibleChild::RecvFocusedChild(const uint64_t& aID,
|
||||
uint64_t* aChild,
|
||||
|
@ -454,16 +454,6 @@ public:
|
||||
|
||||
virtual bool RecvTakeFocus(const uint64_t& aID) override;
|
||||
|
||||
virtual bool RecvEmbeddedChildCount(const uint64_t& aID, uint32_t* aCount)
|
||||
override final;
|
||||
|
||||
virtual bool RecvIndexOfEmbeddedChild(const uint64_t& aID,
|
||||
const uint64_t& aChildID,
|
||||
uint32_t* aChildIdx) override final;
|
||||
|
||||
virtual bool RecvEmbeddedChildAt(const uint64_t& aID, const uint32_t& aIdx,
|
||||
uint64_t* aChildID) override final;
|
||||
|
||||
virtual bool RecvFocusedChild(const uint64_t& aID,
|
||||
uint64_t* aChild,
|
||||
bool* aOk) override;
|
||||
|
@ -237,11 +237,6 @@ child:
|
||||
prio(high) sync Step(uint64_t aID) returns(double aStep);
|
||||
|
||||
async TakeFocus(uint64_t aID);
|
||||
prio(high) sync EmbeddedChildCount(uint64_t aID) returns(uint32_t aCount);
|
||||
prio(high) sync IndexOfEmbeddedChild(uint64_t aID, uint64_t aChildID)
|
||||
returns(uint32_t childIdx);
|
||||
prio(high) sync EmbeddedChildAt(uint64_t aID, uint32_t aChildIdx)
|
||||
returns(uint64_t aChild);
|
||||
prio(high) sync FocusedChild(uint64_t aID)
|
||||
returns(uint64_t aChild, bool aOk);
|
||||
|
||||
|
@ -1035,34 +1035,50 @@ ProxyAccessible::TakeFocus()
|
||||
uint32_t
|
||||
ProxyAccessible::EmbeddedChildCount() const
|
||||
{
|
||||
uint32_t count;
|
||||
Unused << mDoc->SendEmbeddedChildCount(mID, &count);
|
||||
size_t count = 0, kids = mChildren.Length();
|
||||
for (size_t i = 0; i < kids; i++) {
|
||||
if (mChildren[i]->IsEmbeddedObject()) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int32_t
|
||||
ProxyAccessible::IndexOfEmbeddedChild(const ProxyAccessible* aChild)
|
||||
{
|
||||
uint64_t childID = aChild->mID;
|
||||
uint32_t childIdx;
|
||||
Unused << mDoc->SendIndexOfEmbeddedChild(mID, childID, &childIdx);
|
||||
return childIdx;
|
||||
size_t index = 0, kids = mChildren.Length();
|
||||
for (size_t i = 0; i < kids; i++) {
|
||||
if (mChildren[i]->IsEmbeddedObject()) {
|
||||
if (mChildren[i] == aChild) {
|
||||
return index;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ProxyAccessible*
|
||||
ProxyAccessible::EmbeddedChildAt(size_t aChildIdx)
|
||||
{
|
||||
// For an outer doc the only child is a document, which is of course an
|
||||
// embedded child. Further asking the child process for the id of the child
|
||||
// document won't work because the id of the child doc will be 0, which we
|
||||
// would interpret as being our parent document.
|
||||
if (mOuterDoc) {
|
||||
return ChildAt(aChildIdx);
|
||||
size_t index = 0, kids = mChildren.Length();
|
||||
for (size_t i = 0; i < kids; i++) {
|
||||
if (!mChildren[i]->IsEmbeddedObject()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (index == aChildIdx) {
|
||||
return mChildren[i];
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
uint64_t childID;
|
||||
Unused << mDoc->SendEmbeddedChildAt(mID, aChildIdx, &childID);
|
||||
return mDoc->GetAccessible(childID);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ProxyAccessible*
|
||||
|
@ -91,6 +91,17 @@ public:
|
||||
*/
|
||||
role Role() const { return mRole; }
|
||||
|
||||
/**
|
||||
* Return true if this is an embedded object.
|
||||
*/
|
||||
bool IsEmbeddedObject() const
|
||||
{
|
||||
role role = Role();
|
||||
return role != roles::TEXT_LEAF &&
|
||||
role != roles::WHITESPACE &&
|
||||
role != roles::STATICTEXT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the states for the proxied accessible.
|
||||
*/
|
||||
|
@ -14,11 +14,7 @@ export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
|
||||
. $topsrcdir/build/win32/mozconfig.vs2013-win64
|
||||
else
|
||||
. $topsrcdir/build/win32/mozconfig.vs2013
|
||||
fi
|
||||
. $topsrcdir/build/win32/mozconfig.vs-latest
|
||||
|
||||
# B2G Options
|
||||
ac_add_options --enable-application=b2g
|
||||
|
@ -14,11 +14,7 @@ export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
|
||||
. $topsrcdir/build/win32/mozconfig.vs2013-win64
|
||||
else
|
||||
. $topsrcdir/build/win32/mozconfig.vs2013
|
||||
fi
|
||||
. $topsrcdir/build/win32/mozconfig.vs-latest
|
||||
|
||||
# B2G Options
|
||||
ac_add_options --enable-application=b2g
|
||||
|
@ -9,11 +9,7 @@ ac_add_options --enable-js-diagnostics
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
|
||||
. $topsrcdir/build/win32/mozconfig.vs2013-win64
|
||||
else
|
||||
. $topsrcdir/build/win32/mozconfig.vs2013
|
||||
fi
|
||||
. $topsrcdir/build/win32/mozconfig.vs-latest
|
||||
|
||||
# graphene Options
|
||||
ENABLE_MARIONETTE=1
|
||||
|
@ -11,11 +11,7 @@ ac_add_options --enable-js-diagnostics
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
|
||||
. $topsrcdir/build/win32/mozconfig.vs2013-win64
|
||||
else
|
||||
. $topsrcdir/build/win32/mozconfig.vs2013
|
||||
fi
|
||||
. $topsrcdir/build/win32/mozconfig.vs-latest
|
||||
|
||||
# graphene Options
|
||||
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
|
||||
|
@ -26,7 +26,7 @@ ac_add_options --enable-warnings-as-errors
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. $topsrcdir/build/win64/mozconfig.vs2013
|
||||
. $topsrcdir/build/win64/mozconfig.vs-latest
|
||||
|
||||
. "$topsrcdir/build/mozconfig.cache"
|
||||
|
||||
|
@ -8,7 +8,7 @@ fi
|
||||
ac_add_options --target=x86_64-pc-mingw32
|
||||
ac_add_options --host=x86_64-pc-mingw32
|
||||
|
||||
. $topsrcdir/build/win64/mozconfig.vs2013
|
||||
. $topsrcdir/build/win64/mozconfig.vs-latest
|
||||
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
|
@ -9,11 +9,7 @@ ac_add_options --enable-js-diagnostics
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
|
||||
. $topsrcdir/build/win32/mozconfig.vs2013-win64
|
||||
else
|
||||
. $topsrcdir/build/win32/mozconfig.vs2013
|
||||
fi
|
||||
. $topsrcdir/build/win32/mozconfig.vs-latest
|
||||
|
||||
# graphene Options
|
||||
ENABLE_MARIONETTE=1
|
||||
|
@ -11,11 +11,7 @@ ac_add_options --enable-js-diagnostics
|
||||
# Needed to enable breakpad in application.ini
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
|
||||
. $topsrcdir/build/win32/mozconfig.vs2013-win64
|
||||
else
|
||||
. $topsrcdir/build/win32/mozconfig.vs2013
|
||||
fi
|
||||
. $topsrcdir/build/win32/mozconfig.vs-latest
|
||||
|
||||
# graphene Options
|
||||
export CXXFLAGS=-DMOZ_ENABLE_JS_DUMP
|
||||
|
@ -26,7 +26,7 @@ ac_add_options --enable-warnings-as-errors
|
||||
# Package js shell.
|
||||
export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
. $topsrcdir/build/win64/mozconfig.vs2013
|
||||
. $topsrcdir/build/win64/mozconfig.vs-latest
|
||||
|
||||
. "$topsrcdir/build/mozconfig.cache"
|
||||
|
||||
|
@ -8,7 +8,7 @@ fi
|
||||
ac_add_options --target=x86_64-pc-mingw32
|
||||
ac_add_options --host=x86_64-pc-mingw32
|
||||
|
||||
. $topsrcdir/build/win64/mozconfig.vs2013
|
||||
. $topsrcdir/build/win64/mozconfig.vs-latest
|
||||
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
|
@ -27,7 +27,7 @@ export MOZILLA_OFFICIAL=1
|
||||
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
. $topsrcdir/build/win32/mozconfig.vs2015-win64
|
||||
. $topsrcdir/build/win32/mozconfig.vs-latest
|
||||
|
||||
# Treat warnings as errors (modulo ALLOW_COMPILER_WARNINGS).
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
@ -21,7 +21,7 @@ export MOZILLA_OFFICIAL=1
|
||||
# Enable Telemetry
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
. $topsrcdir/build/win32/mozconfig.vs2015-win64
|
||||
. $topsrcdir/build/win32/mozconfig.vs-latest
|
||||
|
||||
# Treat warnings as errors (modulo ALLOW_COMPILER_WARNINGS).
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
@ -10,7 +10,7 @@ ac_add_options --enable-dmd
|
||||
|
||||
ac_add_options --enable-clang-plugin
|
||||
|
||||
. $topsrcdir/build/win32/mozconfig.vs2013-win64
|
||||
. $topsrcdir/build/win32/mozconfig.vs-latest
|
||||
|
||||
# Treat warnings as errors (modulo ALLOW_COMPILER_WARNINGS).
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
@ -11,10 +11,6 @@ export MOZILLA_OFFICIAL=1
|
||||
# Enable Telemetry
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
|
||||
. $topsrcdir/build/win32/mozconfig.vs2015-win64
|
||||
else
|
||||
. $topsrcdir/build/win32/mozconfig.vs2015
|
||||
fi
|
||||
. $topsrcdir/build/win32/mozconfig.vs-latest
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
|
@ -28,7 +28,7 @@ export MOZ_TELEMETRY_REPORTING=1
|
||||
# Treat warnings as errors (modulo ALLOW_COMPILER_WARNINGS).
|
||||
ac_add_options --enable-warnings-as-errors
|
||||
|
||||
. $topsrcdir/build/win64/mozconfig.vs2015
|
||||
. $topsrcdir/build/win64/mozconfig.vs-latest
|
||||
|
||||
# Enable Adobe Primetime and Widevine CDMs on 64-bit Windows in Mozilla builds.
|
||||
# Enabled here on the assumption that downstream vendors will not be using
|
||||
|
@ -31,7 +31,7 @@ export MOZ_PACKAGE_JSSHELL=1
|
||||
|
||||
ac_add_options --with-branding=browser/branding/nightly
|
||||
|
||||
. $topsrcdir/build/win64/mozconfig.vs2015
|
||||
. $topsrcdir/build/win64/mozconfig.vs-latest
|
||||
|
||||
. "$topsrcdir/build/mozconfig.rust"
|
||||
|
||||
|
@ -12,6 +12,6 @@ export MOZILLA_OFFICIAL=1
|
||||
# Enable Telemetry
|
||||
export MOZ_TELEMETRY_REPORTING=1
|
||||
|
||||
. $topsrcdir/build/win64/mozconfig.vs2015
|
||||
. $topsrcdir/build/win64/mozconfig.vs-latest
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
||||
|
@ -9,18 +9,9 @@ GNU_LD=
|
||||
|
||||
GNU_CC=
|
||||
GNU_CXX=
|
||||
dnl moz.configure ensures that the compilers have the same version
|
||||
CXX_VERSION=$CC_VERSION
|
||||
if test "$CC_TYPE" = "gcc"; then
|
||||
GNU_CC=1
|
||||
GNU_CXX=1
|
||||
changequote(<<,>>)
|
||||
GCC_VERSION_FULL="$CXX_VERSION"
|
||||
GCC_VERSION=`echo "$GCC_VERSION_FULL" | $PERL -pe '(split(/\./))[0]>=4&&s/(^\d*\.\d*).*/<<$>>1/;'`
|
||||
|
||||
GCC_MAJOR_VERSION=`echo ${GCC_VERSION} | $AWK -F\. '{ print <<$>>1 }'`
|
||||
GCC_MINOR_VERSION=`echo ${GCC_VERSION} | $AWK -F\. '{ print <<$>>2 }'`
|
||||
changequote([,])
|
||||
fi
|
||||
|
||||
if test "`echo | $AS -o conftest.out -v 2>&1 | grep -c GNU`" != "0"; then
|
||||
@ -31,12 +22,6 @@ if test "`echo | $LD -v 2>&1 | grep -c GNU`" != "0"; then
|
||||
GNU_LD=1
|
||||
fi
|
||||
|
||||
if test "$CC_TYPE" = "msvc"; then
|
||||
MSVC_VERSION_FULL="$CXX_VERSION"
|
||||
CC_VERSION=`echo ${CC_VERSION} | cut -c 1-4`
|
||||
CXX_VERSION=`echo ${CXX_VERSION} | cut -c 1-4`
|
||||
fi
|
||||
|
||||
CLANG_CC=
|
||||
CLANG_CXX=
|
||||
CLANG_CL=
|
||||
@ -48,15 +33,6 @@ if test "$CC_TYPE" = "clang"; then
|
||||
fi
|
||||
if test "$CC_TYPE" = "clang-cl"; then
|
||||
CLANG_CL=1
|
||||
# We force clang-cl to emulate Visual C++ 2013 in configure.in, but that
|
||||
# is based on the CLANG_CL variable defined here, so make sure that we're
|
||||
# getting the right version here manually.
|
||||
CC_VERSION=1800
|
||||
CXX_VERSION=1800
|
||||
MSVC_VERSION_FULL=180030723
|
||||
# Build on clang-cl with MSVC 2013 Update 3 with fallback emulation.
|
||||
CFLAGS="$CFLAGS -fms-compatibility-version=18.00.30723 -fallback"
|
||||
CXXFLAGS="$CXXFLAGS -fms-compatibility-version=18.00.30723 -fallback"
|
||||
fi
|
||||
|
||||
if test "$GNU_CC"; then
|
||||
@ -67,13 +43,6 @@ fi
|
||||
|
||||
AC_SUBST(CLANG_CXX)
|
||||
AC_SUBST(CLANG_CL)
|
||||
|
||||
if test -n "$GNU_CC" -a -z "$CLANG_CC" ; then
|
||||
if test "$GCC_MAJOR_VERSION" -eq 4 -a "$GCC_MINOR_VERSION" -lt 8 ||
|
||||
test "$GCC_MAJOR_VERSION" -lt 4; then
|
||||
AC_MSG_ERROR([Only GCC 4.8 or newer supported])
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([MOZ_CROSS_COMPILER],
|
||||
@ -140,23 +109,6 @@ dnl Updates to the test below should be duplicated further below for the
|
||||
dnl cross-compiling case.
|
||||
AC_LANG_CPLUSPLUS
|
||||
if test "$GNU_CXX"; then
|
||||
CXXFLAGS="$CXXFLAGS -std=gnu++11"
|
||||
_ADDED_CXXFLAGS="-std=gnu++11"
|
||||
|
||||
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, do a feature check. Normally,
|
||||
dnl we'd use __has_feature, but there are unfortunately no C++11
|
||||
dnl differences in clang 3.4. However, it supports the 2013-08-28
|
||||
dnl draft of the ISO WG21 SG10 feature test macro recommendations.
|
||||
AC_TRY_COMPILE([], [#if !__cpp_static_assert
|
||||
#error ISO WG21 SG10 feature test macros unsupported
|
||||
#endif],,AC_MSG_ERROR([Only clang/llvm 3.4 or newer supported]))
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([whether 64-bits std::atomic requires -latomic],
|
||||
ac_cv_needs_atomic,
|
||||
AC_TRY_LINK(
|
||||
@ -182,44 +134,5 @@ if test "$GNU_CXX"; then
|
||||
fi
|
||||
AC_SUBST(MOZ_NEEDS_LIBATOMIC)
|
||||
fi
|
||||
|
||||
if test -n "$CROSS_COMPILE"; then
|
||||
dnl moz.configure ensures that the compilers have the same version
|
||||
HOST_CXX_VERSION=$HOST_CC_VERSION
|
||||
if test "$HOST_CC_TYPE" = "gcc" ; then
|
||||
changequote(<<,>>)
|
||||
HOST_GCC_VERSION_FULL="$HOST_CXX_VERSION"
|
||||
HOST_GCC_VERSION=`echo "$HOST_GCC_VERSION_FULL" | $PERL -pe '(split(/\./))[0]>=4&&s/(^\d*\.\d*).*/<<$>>1/;'`
|
||||
|
||||
HOST_GCC_MAJOR_VERSION=`echo ${HOST_GCC_VERSION} | $AWK -F\. '{ print <<$>>1 }'`
|
||||
HOST_GCC_MINOR_VERSION=`echo ${HOST_GCC_VERSION} | $AWK -F\. '{ print <<$>>2 }'`
|
||||
changequote([,])
|
||||
|
||||
if test "$HOST_GCC_MAJOR_VERSION" -eq 4 -a "$HOST_GCC_MINOR_VERSION" -lt 8 ||
|
||||
test "$HOST_GCC_MAJOR_VERSION" -lt 4; then
|
||||
AC_MSG_ERROR([Only GCC 4.8 or newer supported for host compiler])
|
||||
fi
|
||||
fi
|
||||
|
||||
HOST_CXXFLAGS="$HOST_CXXFLAGS -std=gnu++11"
|
||||
|
||||
_SAVE_CXXFLAGS="$CXXFLAGS"
|
||||
_SAVE_CPPFLAGS="$CPPFLAGS"
|
||||
_SAVE_CXX="$CXX"
|
||||
CXXFLAGS="$HOST_CXXFLAGS"
|
||||
CPPFLAGS="$HOST_CPPFLAGS"
|
||||
CXX="$HOST_CXX"
|
||||
if test "$HOST_CC_TYPE" = clang; then
|
||||
AC_TRY_COMPILE([], [#if !__cpp_static_assert
|
||||
#error ISO WG21 SG10 feature test macros unsupported
|
||||
#endif],,AC_MSG_ERROR([Only clang/llvm 3.4 or newer supported]))
|
||||
fi
|
||||
|
||||
CXXFLAGS="$_SAVE_CXXFLAGS"
|
||||
CPPFLAGS="$_SAVE_CPPFLAGS"
|
||||
CXX="$_SAVE_CXX"
|
||||
elif test "$GNU_CXX"; then
|
||||
HOST_CXXFLAGS="$HOST_CXXFLAGS $_ADDED_CXXFLAGS"
|
||||
fi
|
||||
AC_LANG_C
|
||||
])
|
||||
|
@ -39,7 +39,7 @@ def android_toolchain(target, host, ndk, toolchain, gnu_compiler_version):
|
||||
target_base = 'arm-linux-androideabi'
|
||||
elif target.cpu == 'x86':
|
||||
target_base = 'x86'
|
||||
elif target.cpu == 'mips' and target.endianness == 'little':
|
||||
elif target.cpu == 'mips32' and target.endianness == 'little':
|
||||
target_base = 'mipsel-linux-android'
|
||||
else:
|
||||
die('Target cpu is not supported.')
|
||||
|
@ -13,7 +13,6 @@
|
||||
# destructure in the assignment below the function declaration.
|
||||
@template
|
||||
@imports(_from='__builtin__', _import='Exception')
|
||||
@imports(_from='__builtin__', _import='__name__')
|
||||
def _declare_exceptions():
|
||||
class FatalCheckError(Exception):
|
||||
'''An exception to throw from a function decorated with @checking.
|
||||
|
@ -147,7 +147,7 @@ def add_old_configure_assignment(var, value):
|
||||
else:
|
||||
if isinstance(value, (list, tuple)):
|
||||
value = quote(*value)
|
||||
assignments.append('%s=%s' % (var, quote(value)))
|
||||
assignments.append('%s=%s' % (var, quote(str(value))))
|
||||
|
||||
@template
|
||||
def add_old_configure_arg(arg):
|
||||
@ -313,6 +313,10 @@ option('--target', nargs=1,
|
||||
help='Define the system type where the resulting executables will be '
|
||||
'used')
|
||||
|
||||
@imports(_from='mozbuild.configure.constants', _import='CPU')
|
||||
@imports(_from='mozbuild.configure.constants', _import='Endianness')
|
||||
@imports(_from='mozbuild.configure.constants', _import='Kernel')
|
||||
@imports(_from='mozbuild.configure.constants', _import='OS')
|
||||
def split_triplet(triplet):
|
||||
# The standard triplet is defined as
|
||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
|
||||
@ -408,10 +412,10 @@ def split_triplet(triplet):
|
||||
|
||||
return namespace(
|
||||
alias=triplet,
|
||||
cpu=canonical_cpu,
|
||||
kernel=canonical_kernel,
|
||||
os=canonical_os,
|
||||
endianness=endianness,
|
||||
cpu=CPU(canonical_cpu),
|
||||
kernel=Kernel(canonical_kernel),
|
||||
os=OS(canonical_os),
|
||||
endianness=Endianness(endianness),
|
||||
raw_cpu=cpu,
|
||||
raw_os=os,
|
||||
# Toolchains, most notably for cross compilation may use cpu-os
|
||||
@ -493,7 +497,7 @@ def target_variables(target):
|
||||
os_target = target.os
|
||||
os_arch = target.kernel
|
||||
|
||||
if target.os == 'Darwin' and target.cpu == 'x86':
|
||||
if target.kernel == 'Darwin' and target.cpu == 'x86':
|
||||
os_test = 'i386'
|
||||
else:
|
||||
os_test = target.raw_cpu
|
||||
|
@ -153,22 +153,7 @@ add_old_configure_assignment('TOOLCHAIN_PREFIX', toolchain_prefix)
|
||||
@imports(_from='mozbuild.configure.util', _import='LineIO')
|
||||
@imports(_from='mozbuild.shellutil', _import='quote')
|
||||
@imports(_from='tempfile', _import='mkstemp')
|
||||
@imports(_from='textwrap', _import='dedent')
|
||||
def check_compiler(compiler, language):
|
||||
check = dedent('''\
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(__clang__)
|
||||
COMPILER clang-cl _MSC_VER
|
||||
#else
|
||||
COMPILER msvc _MSC_FULL_VER
|
||||
#endif
|
||||
#elif defined(__clang__)
|
||||
COMPILER clang __clang_major__.__clang_minor__.__clang_patchlevel__
|
||||
#elif defined(__GNUC__)
|
||||
COMPILER gcc __GNUC__.__GNUC_MINOR__.__GNUC_PATCHLEVEL__
|
||||
#endif
|
||||
''')
|
||||
|
||||
def try_preprocess(compiler, language, source):
|
||||
suffix = {
|
||||
'C': '.c',
|
||||
'C++': '.cpp',
|
||||
@ -176,7 +161,7 @@ def check_compiler(compiler, language):
|
||||
|
||||
fd, path = mkstemp(prefix='conftest.', suffix=suffix)
|
||||
try:
|
||||
source = check.encode('ascii', 'replace')
|
||||
source = source.encode('ascii', 'replace')
|
||||
|
||||
log.debug('Creating `%s` with content:', path)
|
||||
with LineIO(lambda l: log.debug('| %s', l)) as out:
|
||||
@ -192,12 +177,7 @@ def check_compiler(compiler, language):
|
||||
stdout, stderr = proc.communicate()
|
||||
retcode = proc.wait()
|
||||
if retcode == 0:
|
||||
for line in stdout.splitlines():
|
||||
if line.startswith('COMPILER '):
|
||||
_, type, version = line.split(None, 2)
|
||||
version = version.replace(' ', '')
|
||||
return type, version
|
||||
return
|
||||
return stdout
|
||||
|
||||
log.debug('The command returned non-zero exit status %d.', retcode)
|
||||
for out, desc in ((stdout, 'output'), (stderr, 'error output')):
|
||||
@ -209,6 +189,148 @@ def check_compiler(compiler, language):
|
||||
os.remove(path)
|
||||
|
||||
|
||||
@imports(_from='mozbuild.configure.constants', _import='CompilerType')
|
||||
@imports(_from='textwrap', _import='dedent')
|
||||
def get_compiler_info(compiler, language):
|
||||
'''Returns information about the given `compiler` (command line in the
|
||||
form of a list or tuple), in the given `language`.
|
||||
|
||||
The returned information includes:
|
||||
- the compiler type (msvc, clang-cl, clang or gcc)
|
||||
- the compiler version
|
||||
- the compiler supported language
|
||||
- the compiler supported language version
|
||||
'''
|
||||
# Note: MSVC doesn't expose __STDC_VERSION__. It does expose __STDC__,
|
||||
# but only when given the -Za option, which disables compiler
|
||||
# extensions.
|
||||
# Note: We'd normally do a version check for clang, but versions of clang
|
||||
# in Xcode have a completely different versioning scheme despite exposing
|
||||
# the version with the same defines.
|
||||
# So instead, we make things such that the version is missing when the
|
||||
# clang used is below the minimum supported version (currently clang 3.4).
|
||||
# Normally, we'd use __has_feature, but there are unfortunately no C++11
|
||||
# differences in clang 3.4. However, it supports the 2013-08-28 draft of
|
||||
# the ISO WG21 SG10 feature test macro recommendations, and thus exposes
|
||||
# new __cpp_* macros that older clang versions didn't.
|
||||
# We then only include the version information when the C++ compiler
|
||||
# matches the feature check, so that an unsupported version of clang would
|
||||
# have no version number.
|
||||
check = dedent('''\
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(__clang__)
|
||||
%COMPILER clang-cl
|
||||
%VERSION _MSC_FULL_VER
|
||||
#else
|
||||
%COMPILER msvc
|
||||
%VERSION _MSC_FULL_VER
|
||||
#endif
|
||||
#elif defined(__clang__)
|
||||
%COMPILER clang
|
||||
# if !__cplusplus || __cpp_static_assert
|
||||
%VERSION __clang_major__.__clang_minor__.__clang_patchlevel__
|
||||
# endif
|
||||
#elif defined(__GNUC__)
|
||||
%COMPILER gcc
|
||||
%VERSION __GNUC__.__GNUC_MINOR__.__GNUC_PATCHLEVEL__
|
||||
#endif
|
||||
|
||||
#if __cplusplus
|
||||
%cplusplus __cplusplus
|
||||
#elif __STDC_VERSION__
|
||||
%STDC_VERSION __STDC_VERSION__
|
||||
#elif __STDC__
|
||||
%STDC_VERSION 198900L
|
||||
#endif
|
||||
''')
|
||||
|
||||
result = try_preprocess(compiler, language, check)
|
||||
|
||||
if not result:
|
||||
raise FatalCheckError(
|
||||
'Unknown compiler or compiler not supported.')
|
||||
|
||||
data = {}
|
||||
for line in result.splitlines():
|
||||
if line.startswith('%'):
|
||||
k, _, v = line.partition(' ')
|
||||
k = k.lstrip('%')
|
||||
data[k] = v.replace(' ', '')
|
||||
log.debug('%s = %s', k, data[k])
|
||||
|
||||
try:
|
||||
type = CompilerType(data['COMPILER'])
|
||||
except:
|
||||
raise FatalCheckError(
|
||||
'Unknown compiler or compiler not supported.')
|
||||
|
||||
cplusplus = int(data.get('cplusplus', '0L').rstrip('L'))
|
||||
stdc_version = int(data.get('STDC_VERSION', '0L').rstrip('L'))
|
||||
|
||||
version = data.get('VERSION')
|
||||
if version and type in ('msvc', 'clang-cl'):
|
||||
msc_ver = version
|
||||
version = msc_ver[0:2]
|
||||
if len(msc_ver) > 2:
|
||||
version += '.' + msc_ver[2:4]
|
||||
if len(msc_ver) > 4:
|
||||
version += '.' + msc_ver[4:]
|
||||
|
||||
if version:
|
||||
version = Version(version)
|
||||
|
||||
return namespace(
|
||||
type=type,
|
||||
version=version,
|
||||
language='C++' if cplusplus else 'C',
|
||||
language_version=cplusplus if cplusplus else stdc_version,
|
||||
)
|
||||
|
||||
|
||||
@imports(_from='mozbuild.shellutil', _import='quote')
|
||||
def check_compiler(compiler, language):
|
||||
info = get_compiler_info(compiler, language)
|
||||
|
||||
flags = []
|
||||
|
||||
def append_flag(flag):
|
||||
if flag not in flags:
|
||||
if info.type == 'clang-cl':
|
||||
flags.append('-Xclang')
|
||||
flags.append(flag)
|
||||
|
||||
# Check language standards
|
||||
# --------------------------------------------------------------------
|
||||
if language != info.language:
|
||||
raise FatalCheckError(
|
||||
'`%s` is not a %s compiler.' % (quote(*compiler), language))
|
||||
|
||||
# Note: We do a strict version check because there sometimes are backwards
|
||||
# incompatible changes in the standard, and not all code that compiles as
|
||||
# C99 compiles as e.g. C11 (as of writing, this is true of libnestegg, for
|
||||
# example)
|
||||
if info.language == 'C' and info.language_version != 199901:
|
||||
if info.type in ('clang-cl', 'clang', 'gcc'):
|
||||
append_flag('-std=gnu99')
|
||||
|
||||
# Note: MSVC, while supporting C++11, still reports 199711L for __cplusplus.
|
||||
# Note: this is a strict version check because we used to always add
|
||||
# -std=gnu++11.
|
||||
if info.language == 'C++' and info.language_version != 201103:
|
||||
if info.type in ('clang-cl', 'clang', 'gcc'):
|
||||
append_flag('-std=gnu++11')
|
||||
|
||||
# We force clang-cl to emulate Visual C++ 2013 Update 3 with fallback to
|
||||
# cl.exe.
|
||||
if info.type == 'clang-cl' and info.version != '18.00.30723':
|
||||
# Those flags are direct clang-cl flags that don't need -Xclang, add
|
||||
# them directly.
|
||||
flags.append('-fms-compatibility-version=18.00.30723')
|
||||
flags.append('-fallback')
|
||||
|
||||
return info.type, info.version, flags
|
||||
|
||||
|
||||
@template
|
||||
def default_c_compilers(host_or_target):
|
||||
'''Template defining the set of default C compilers for the host and
|
||||
@ -335,7 +457,7 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None):
|
||||
input=delayed_getattr(provided_compiler, 'compiler'))
|
||||
|
||||
@depends(compiler, provided_compiler, compiler_wrapper)
|
||||
@checking('%s version' % what, lambda x: x.version if x else 'not found')
|
||||
@checking('whether %s can be used' % what, lambda x: bool(x))
|
||||
@imports(_from='mozbuild.shellutil', _import='quote')
|
||||
def valid_compiler(compiler, provided_compiler, compiler_wrapper):
|
||||
wrapper = list(compiler_wrapper or ())
|
||||
@ -371,17 +493,58 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None):
|
||||
quote(os.path.dirname(found_compiler)),
|
||||
quote(os.path.dirname(full_path)))
|
||||
|
||||
result = check_compiler(wrapper + [compiler] + flags, language)
|
||||
if result:
|
||||
type, version = result
|
||||
return namespace(
|
||||
wrapper=wrapper,
|
||||
compiler=compiler,
|
||||
flags=flags,
|
||||
type=type,
|
||||
version=version,
|
||||
)
|
||||
die('Failed to get the compiler version')
|
||||
type, version, more_flags = check_compiler(
|
||||
wrapper + [compiler] + flags, language)
|
||||
|
||||
# Check that the additional flags we got are enough to not require any
|
||||
# more flags.
|
||||
if more_flags:
|
||||
flags += more_flags
|
||||
type, version, more_flags = check_compiler(
|
||||
wrapper + [compiler] + flags, language)
|
||||
|
||||
if more_flags:
|
||||
raise FatalCheckError(
|
||||
'Unknown compiler or compiler not supported.')
|
||||
|
||||
# Compiler version checks
|
||||
# ===================================================
|
||||
# Check the compiler version here instead of in `compiler_version` so
|
||||
# that the `checking` message doesn't pretend the compiler can be used
|
||||
# to then bail out one line later.
|
||||
if type == 'gcc' and version < '4.8.0':
|
||||
raise FatalCheckError(
|
||||
'Only GCC 4.8 or newer is supported (found version %s).'
|
||||
% version)
|
||||
|
||||
# If you want to bump the version check here search for
|
||||
# __cpp_static_assert above, and see the associated comment.
|
||||
if type == 'clang' and not version:
|
||||
raise FatalCheckError(
|
||||
'Only clang/llvm 3.4 or newer is supported.')
|
||||
|
||||
if type == 'msvc':
|
||||
if version < '18.00.30723' or ('19' < version < '19.00.23506'):
|
||||
raise FatalCheckError(
|
||||
'This version (%s) of the MSVC compiler is not '
|
||||
'supported.\n'
|
||||
'You must install Visual C++ 2013 Update 3, Visual '
|
||||
'C++ 2015 Update 1, or newer in order to build.\n'
|
||||
'See https://developer.mozilla.org/en/'
|
||||
'Windows_Build_Prerequisites' % version)
|
||||
|
||||
return namespace(
|
||||
wrapper=wrapper,
|
||||
compiler=compiler,
|
||||
flags=flags,
|
||||
type=type,
|
||||
version=version,
|
||||
)
|
||||
|
||||
@depends(valid_compiler)
|
||||
@checking('%s version' % what)
|
||||
def compiler_version(compiler):
|
||||
return compiler.version
|
||||
|
||||
if language == 'C++':
|
||||
@depends(valid_compiler, c_compiler)
|
||||
|
1
build/win32/mozconfig.vs-latest
Normal file
1
build/win32/mozconfig.vs-latest
Normal file
@ -0,0 +1 @@
|
||||
. $topsrcdir/build/win32/mozconfig.vs2015-win64
|
@ -1,13 +0,0 @@
|
||||
export INCLUDE=/d/msvs10/vc/include:/d/msvs10/vc/atlmfc/include:/d/sdks/v7.0/include:/d/sdks/v7.0/include/atl:/d/msvs8/VC/PlatformSDK/include:/d/sdks/dx10/include
|
||||
export LIBPATH=/d/msvs10/vc/lib:/d/msvs10/vc/atlmfc/lib:/c/WINDOWS/Microsoft.NET/Framework/v2.0.50727
|
||||
export LIB=/d/msvs10/vc/lib:/d/msvs10/vc/atlmfc/lib:/d/sdks/v7.0/lib:/d/msvs8/VC/PlatformSDK/lib:/d/msvs8/SDK/v2.0/lib:/d/mozilla-build/atlthunk_compat:/d/sdks/dx10/lib/x86
|
||||
export PATH="/d/msvs10/VSTSDB/Deploy:/d/msvs10/Common7/IDE/:/d/msvs10/VC/BIN:/d/msvs10/Common7/Tools:/d/msvs10/VC/VCPackages:${PATH}"
|
||||
export WIN32_REDIST_DIR=/d/msvs10/VC/redist/x86/Microsoft.VC100.CRT
|
||||
|
||||
. $topsrcdir/build/mozconfig.vs-common
|
||||
|
||||
mk_export_correct_style LIB
|
||||
mk_export_correct_style LIBPATH
|
||||
mk_export_correct_style PATH
|
||||
mk_export_correct_style INCLUDE
|
||||
mk_export_correct_style WIN32_REDIST_DIR
|
1
build/win64/mozconfig.vs-latest
Normal file
1
build/win64/mozconfig.vs-latest
Normal file
@ -0,0 +1 @@
|
||||
. $topsrcdir/build/win64/mozconfig.vs2015
|
@ -1,6 +1,6 @@
|
||||
/******************************************************************************
|
||||
** This file is an amalgamation of many separate C source files from SQLite
|
||||
** version 3.12.1. By combining all the individual C code files into this
|
||||
** version 3.12.2. By combining all the individual C code files into this
|
||||
** single large file, the entire code can be compiled as a single translation
|
||||
** unit. This allows many compilers to do optimizations that would not be
|
||||
** possible if the files were compiled separately. Performance improvements
|
||||
@ -336,9 +336,9 @@ extern "C" {
|
||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "3.12.1"
|
||||
#define SQLITE_VERSION_NUMBER 3012001
|
||||
#define SQLITE_SOURCE_ID "2016-04-08 15:09:49 fe7d3b75fe1bde41511b323925af8ae1b910bc4d"
|
||||
#define SQLITE_VERSION "3.12.2"
|
||||
#define SQLITE_VERSION_NUMBER 3012002
|
||||
#define SQLITE_SOURCE_ID "2016-04-18 17:30:31 92dc59fd5ad66f646666042eb04195e3a61a9e8e"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
@ -63941,6 +63941,28 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
|
||||
pPage = pCur->apPage[iCellDepth];
|
||||
pCell = findCell(pPage, iCellIdx);
|
||||
|
||||
/* If the bPreserve flag is set to true, then the cursor position must
|
||||
** be preserved following this delete operation. If the current delete
|
||||
** will cause a b-tree rebalance, then this is done by saving the cursor
|
||||
** key and leaving the cursor in CURSOR_REQUIRESEEK state before
|
||||
** returning.
|
||||
**
|
||||
** Or, if the current delete will not cause a rebalance, then the cursor
|
||||
** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
|
||||
** before or after the deleted entry. In this case set bSkipnext to true. */
|
||||
if( bPreserve ){
|
||||
if( !pPage->leaf
|
||||
|| (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
|
||||
){
|
||||
/* A b-tree rebalance will be required after deleting this entry.
|
||||
** Save the cursor key. */
|
||||
rc = saveCursorKey(pCur);
|
||||
if( rc ) return rc;
|
||||
}else{
|
||||
bSkipnext = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* If the page containing the entry to delete is not a leaf page, move
|
||||
** the cursor to the largest entry in the tree that is smaller than
|
||||
** the entry being deleted. This cell will replace the cell being deleted
|
||||
@ -63967,28 +63989,6 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
|
||||
invalidateIncrblobCursors(p, pCur->info.nKey, 0);
|
||||
}
|
||||
|
||||
/* If the bPreserve flag is set to true, then the cursor position must
|
||||
** be preserved following this delete operation. If the current delete
|
||||
** will cause a b-tree rebalance, then this is done by saving the cursor
|
||||
** key and leaving the cursor in CURSOR_REQUIRESEEK state before
|
||||
** returning.
|
||||
**
|
||||
** Or, if the current delete will not cause a rebalance, then the cursor
|
||||
** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
|
||||
** before or after the deleted entry. In this case set bSkipnext to true. */
|
||||
if( bPreserve ){
|
||||
if( !pPage->leaf
|
||||
|| (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
|
||||
){
|
||||
/* A b-tree rebalance will be required after deleting this entry.
|
||||
** Save the cursor key. */
|
||||
rc = saveCursorKey(pCur);
|
||||
if( rc ) return rc;
|
||||
}else{
|
||||
bSkipnext = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make the page containing the entry to be deleted writable. Then free any
|
||||
** overflow pages associated with the entry and finally remove the cell
|
||||
** itself from within the page. */
|
||||
@ -82769,7 +82769,6 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
|
||||
){
|
||||
int pgsz; /* Page size of main database */
|
||||
int i; /* Used to iterate through aTask[] */
|
||||
int mxCache; /* Cache size */
|
||||
VdbeSorter *pSorter; /* The new sorter */
|
||||
KeyInfo *pKeyInfo; /* Copy of pCsr->pKeyInfo with db==0 */
|
||||
int szKeyInfo; /* Size of pCsr->pKeyInfo in bytes */
|
||||
@ -82826,11 +82825,20 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit(
|
||||
}
|
||||
|
||||
if( !sqlite3TempInMemory(db) ){
|
||||
i64 mxCache; /* Cache size in bytes*/
|
||||
u32 szPma = sqlite3GlobalConfig.szPma;
|
||||
pSorter->mnPmaSize = szPma * pgsz;
|
||||
|
||||
mxCache = db->aDb[0].pSchema->cache_size;
|
||||
if( mxCache<(int)szPma ) mxCache = (int)szPma;
|
||||
pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_PMASZ);
|
||||
if( mxCache<0 ){
|
||||
/* A negative cache-size value C indicates that the cache is abs(C)
|
||||
** KiB in size. */
|
||||
mxCache = mxCache * -1024;
|
||||
}else{
|
||||
mxCache = mxCache * pgsz;
|
||||
}
|
||||
mxCache = MIN(mxCache, SQLITE_MAX_PMASZ);
|
||||
pSorter->mxPmaSize = MAX(pSorter->mnPmaSize, (int)mxCache);
|
||||
|
||||
/* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
|
||||
** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
|
||||
@ -95563,6 +95571,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
|
||||
zType = z + sqlite3Strlen30(z) + 1;
|
||||
memcpy(zType, pType->z, pType->n);
|
||||
zType[pType->n] = 0;
|
||||
sqlite3Dequote(zType);
|
||||
pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst);
|
||||
pCol->colFlags |= COLFLAG_HASTYPE;
|
||||
}
|
||||
@ -121360,7 +121369,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart(
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
|
||||
/* These registers need to be preserved in case there is an IN operator
|
||||
** loop. So we could deallocate the registers here (and potentially
|
||||
** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems
|
||||
** simpler and safer to simply not reuse the registers.
|
||||
**
|
||||
** sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
|
||||
*/
|
||||
sqlite3ExprCachePop(pParse);
|
||||
}else
|
||||
#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
||||
@ -185458,7 +185473,7 @@ static void fts5SourceIdFunc(
|
||||
){
|
||||
assert( nArg==0 );
|
||||
UNUSED_PARAM2(nArg, apUnused);
|
||||
sqlite3_result_text(pCtx, "fts5: 2016-04-08 15:09:49 fe7d3b75fe1bde41511b323925af8ae1b910bc4d", -1, SQLITE_TRANSIENT);
|
||||
sqlite3_result_text(pCtx, "fts5: 2016-04-18 17:30:31 92dc59fd5ad66f646666042eb04195e3a61a9e8e", -1, SQLITE_TRANSIENT);
|
||||
}
|
||||
|
||||
static int fts5Init(sqlite3 *db){
|
||||
|
@ -111,9 +111,9 @@ extern "C" {
|
||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "3.12.1"
|
||||
#define SQLITE_VERSION_NUMBER 3012001
|
||||
#define SQLITE_SOURCE_ID "2016-04-08 15:09:49 fe7d3b75fe1bde41511b323925af8ae1b910bc4d"
|
||||
#define SQLITE_VERSION "3.12.2"
|
||||
#define SQLITE_VERSION_NUMBER 3012002
|
||||
#define SQLITE_SOURCE_ID "2016-04-18 17:30:31 92dc59fd5ad66f646666042eb04195e3a61a9e8e"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
|
@ -14,7 +14,7 @@
|
||||
*/
|
||||
|
||||
:-moz-native-anonymous .highlighter-container {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* The container for all highlighters doesn't react to pointer-events by
|
||||
|
@ -505,19 +505,6 @@ KeyframeUtils::GetAnimationPropertiesFromKeyframes(
|
||||
MOZ_ASSERT(values.Length() == 1,
|
||||
"Longhand properties should produce a single"
|
||||
" StyleAnimationValue");
|
||||
|
||||
// 'visibility' requires special handling that is unique to CSS
|
||||
// Transitions/CSS Animations/Web Animations (i.e. not SMIL) so we
|
||||
// apply that here.
|
||||
//
|
||||
// Bug 1259285 - Move this code to StyleAnimationValue
|
||||
if (pair.mProperty == eCSSProperty_visibility) {
|
||||
MOZ_ASSERT(values[0].mValue.GetUnit() ==
|
||||
StyleAnimationValue::eUnit_Enumerated,
|
||||
"unexpected unit");
|
||||
values[0].mValue.SetIntValue(values[0].mValue.GetIntValue(),
|
||||
StyleAnimationValue::eUnit_Visibility);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& value : values) {
|
||||
|
@ -25,14 +25,14 @@ test(function(t) {
|
||||
test(function(t) {
|
||||
var div = addDiv(t, {style: 'animation: moveAnimation 100s -10s'});
|
||||
var effect = div.getAnimations()[0].effect;
|
||||
assert_equals(effect.getComputedTiming().delay, -10000,
|
||||
assert_equals(effect.getComputedTiming().delay, -10 * MS_PER_SEC,
|
||||
'Initial value of delay');
|
||||
}, 'Negative delay of a new animation');
|
||||
|
||||
test(function(t) {
|
||||
var div = addDiv(t, {style: 'animation: moveAnimation 100s 10s'});
|
||||
var effect = div.getAnimations()[0].effect;
|
||||
assert_equals(effect.getComputedTiming().delay, 10000,
|
||||
assert_equals(effect.getComputedTiming().delay, 10 * MS_PER_SEC,
|
||||
'Initial value of delay');
|
||||
}, 'Positive delay of a new animation');
|
||||
|
||||
@ -114,7 +114,7 @@ test(function(t) {
|
||||
test(function(t) {
|
||||
var div = addDiv(t, {style: 'animation: moveAnimation 100s -10s infinite'});
|
||||
var effect = div.getAnimations()[0].effect;
|
||||
assert_equals(effect.getComputedTiming().duration, 100000,
|
||||
assert_equals(effect.getComputedTiming().duration, 100 * MS_PER_SEC,
|
||||
'Initial value of duration');
|
||||
}, 'duration of a new animation');
|
||||
|
||||
@ -161,14 +161,14 @@ test(function(t) {
|
||||
test(function(t) {
|
||||
var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
|
||||
var effect = div.getAnimations()[0].effect;
|
||||
assert_equals(effect.getComputedTiming().endTime, 100000,
|
||||
assert_equals(effect.getComputedTiming().endTime, 100 * MS_PER_SEC,
|
||||
'Initial value of endTime');
|
||||
}, 'endTime of an new animation');
|
||||
|
||||
test(function(t) {
|
||||
var div = addDiv(t, {style: 'animation: moveAnimation 100s -5s'});
|
||||
var effect = div.getAnimations()[0].effect;
|
||||
var answer = 100000 - 5000; // ms
|
||||
var answer = (100 - 5) * MS_PER_SEC;
|
||||
assert_equals(effect.getComputedTiming().endTime, answer,
|
||||
'Initial value of endTime');
|
||||
}, 'endTime of an animation with a negative delay');
|
||||
@ -183,7 +183,7 @@ test(function(t) {
|
||||
test(function(t) {
|
||||
var div = addDiv(t, {style: 'animation: moveAnimation 0s 100s infinite'});
|
||||
var effect = div.getAnimations()[0].effect;
|
||||
assert_equals(effect.getComputedTiming().endTime, 100000,
|
||||
assert_equals(effect.getComputedTiming().endTime, 100 * MS_PER_SEC,
|
||||
'Initial value of endTime');
|
||||
}, 'endTime of an infinitely repeating zero-duration animation');
|
||||
|
||||
@ -192,7 +192,7 @@ test(function(t) {
|
||||
// undefined value.
|
||||
var div = addDiv(t, {style: 'animation: moveAnimation 10s -100s forwards'});
|
||||
var effect = div.getAnimations()[0].effect;
|
||||
assert_equals(effect.getComputedTiming().endTime, -90000,
|
||||
assert_equals(effect.getComputedTiming().endTime, -90 * MS_PER_SEC,
|
||||
'Initial value of endTime');
|
||||
}, 'endTime of an animation that finishes before its startTime');
|
||||
|
||||
@ -204,7 +204,7 @@ test(function(t) {
|
||||
test(function(t) {
|
||||
var div = addDiv(t, {style: 'animation: moveAnimation 100s 5'});
|
||||
var effect = div.getAnimations()[0].effect;
|
||||
var answer = 100000 * 5; // ms
|
||||
var answer = 100 * MS_PER_SEC * 5;
|
||||
assert_equals(effect.getComputedTiming().activeDuration, answer,
|
||||
'Initial value of activeDuration');
|
||||
}, 'activeDuration of a new animation');
|
||||
@ -248,25 +248,25 @@ test(function(t) {
|
||||
test(function(t) {
|
||||
var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
|
||||
var anim = div.getAnimations()[0];
|
||||
anim.currentTime = 5000;
|
||||
anim.currentTime = 5 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().localTime, anim.currentTime,
|
||||
'current localTime after setting currentTime');
|
||||
}, 'localTime of an animation is always equal to currentTime');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {style: 'animation: moveAnimation 100s'});
|
||||
|
||||
var anim = div.getAnimations()[0];
|
||||
anim.playbackRate = 2; // 2 times faster
|
||||
|
||||
anim.ready.then(t.step_func(function() {
|
||||
return anim.ready.then(function() {
|
||||
assert_equals(anim.effect.getComputedTiming().localTime, anim.currentTime,
|
||||
'localTime is equal to currentTime');
|
||||
return waitForFrame();
|
||||
})).then(t.step_func_done(function() {
|
||||
}).then(function() {
|
||||
assert_equals(anim.effect.getComputedTiming().localTime, anim.currentTime,
|
||||
'localTime is equal to currentTime');
|
||||
}));
|
||||
});
|
||||
}, 'localTime reflects playbackRate immediately');
|
||||
|
||||
test(function(t) {
|
||||
@ -306,13 +306,13 @@ test(function(t) {
|
||||
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.0,
|
||||
'Initial value of progress');
|
||||
anim.currentTime += 2500;
|
||||
anim.currentTime += 2.5 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.25,
|
||||
'Value of progress');
|
||||
anim.currentTime += 5000;
|
||||
anim.currentTime += 5 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.75,
|
||||
'Value of progress');
|
||||
anim.currentTime += 5000;
|
||||
anim.currentTime += 5 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.25,
|
||||
'Value of progress');
|
||||
anim.finish()
|
||||
@ -334,7 +334,7 @@ test(function(t) {
|
||||
'Initial value of progress in after phase');
|
||||
|
||||
// Seek backwards
|
||||
anim.currentTime -= 1000;
|
||||
anim.currentTime -= 1 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.0,
|
||||
'Value of progress before phase');
|
||||
}, 'progress of an infinitely repeating zero-duration animation');
|
||||
@ -348,7 +348,7 @@ test(function(t) {
|
||||
'Initial value of progress in after phase');
|
||||
|
||||
// Seek backwards
|
||||
anim.currentTime -= 1000;
|
||||
anim.currentTime -= 1 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.0,
|
||||
'Value of progress before phase');
|
||||
}, 'progress of a finitely repeating zero-duration animation');
|
||||
@ -387,13 +387,13 @@ test(function(t) {
|
||||
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.0,
|
||||
'Initial value of progress');
|
||||
anim.currentTime += 2500;
|
||||
anim.currentTime += 2.5 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.25,
|
||||
'Value of progress');
|
||||
anim.currentTime += 5000;
|
||||
anim.currentTime += 5 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.75,
|
||||
'Value of progress');
|
||||
anim.currentTime += 5000;
|
||||
anim.currentTime += 5 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.75,
|
||||
'Value of progress');
|
||||
anim.finish()
|
||||
@ -408,13 +408,13 @@ test(function(t) {
|
||||
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1.0,
|
||||
'Initial value of progress');
|
||||
anim.currentTime += 2500;
|
||||
anim.currentTime += 2.5 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.75,
|
||||
'Value of progress');
|
||||
anim.currentTime += 5000;
|
||||
anim.currentTime += 5 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.25,
|
||||
'Value of progress');
|
||||
anim.currentTime += 5000;
|
||||
anim.currentTime += 5 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.25,
|
||||
'Value of progress');
|
||||
anim.finish()
|
||||
@ -429,10 +429,10 @@ test(function(t) {
|
||||
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.25,
|
||||
'Initial value of progress');
|
||||
anim.currentTime += 2500;
|
||||
anim.currentTime += 2.5 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.25,
|
||||
'Value of progress');
|
||||
anim.currentTime -= 5000;
|
||||
anim.currentTime -= 5 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.0,
|
||||
'Value of progress');
|
||||
anim.finish()
|
||||
@ -447,10 +447,10 @@ test(function(t) {
|
||||
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.75,
|
||||
'Initial value of progress');
|
||||
anim.currentTime += 2500;
|
||||
anim.currentTime += 2.5 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 0.75,
|
||||
'Value of progress');
|
||||
anim.currentTime -= 5000;
|
||||
anim.currentTime -= 5 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().progress, 1.0,
|
||||
'Value of progress');
|
||||
anim.finish()
|
||||
@ -491,7 +491,7 @@ test(function(t) {
|
||||
'Initial value of currentIteration in after phase');
|
||||
|
||||
// Seek backwards
|
||||
anim.currentTime -= 2000;
|
||||
anim.currentTime -= 2 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
|
||||
'Value of currentIteration count during before phase');
|
||||
}, 'currentIteration of an infinitely repeating zero-duration animation');
|
||||
@ -505,7 +505,7 @@ test(function(t) {
|
||||
'Initial value of currentIteration');
|
||||
|
||||
// Seek backwards
|
||||
anim.currentTime -= 2000;
|
||||
anim.currentTime -= 2 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 0,
|
||||
'Value of currentIteration count during before phase');
|
||||
}, 'currentIteration of a finitely repeating zero-duration animation');
|
||||
@ -518,7 +518,7 @@ test(function(t) {
|
||||
'Initial value of currentIteration');
|
||||
// The 3rd iteration
|
||||
// Note: currentIteration = floor(scaled active time / iteration duration)
|
||||
anim.currentTime = 250000; // ms
|
||||
anim.currentTime = 250 * MS_PER_SEC;
|
||||
assert_equals(anim.effect.getComputedTiming().currentIteration, 2,
|
||||
'Value of currentIteration during the 3rd iteration');
|
||||
// Finish
|
||||
|
@ -39,8 +39,8 @@
|
||||
|
||||
const CSS_ANIM_EVENTS =
|
||||
['animationstart', 'animationiteration', 'animationend'];
|
||||
const ANIM_DELAY_MS = 1000000; // 1000s
|
||||
const ANIM_DUR_MS = 1000000; // 1000s
|
||||
const ANIM_DELAY_MS = 1000 * MS_PER_SEC;
|
||||
const ANIM_DUR_MS = 1000 * MS_PER_SEC;
|
||||
const ANIM_PROPERTY_VAL = 'anim ' + ANIM_DUR_MS + 'ms ' + ANIM_DELAY_MS + 'ms';
|
||||
|
||||
/**
|
||||
@ -186,7 +186,6 @@ function checkStateAtActiveIntervalEndTime(animation)
|
||||
'animation-fill-mode is none');
|
||||
}
|
||||
|
||||
|
||||
test(function(t)
|
||||
{
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
@ -224,8 +223,7 @@ test(function(t)
|
||||
}, 'Sanity test to check round-tripping assigning to new animation\'s ' +
|
||||
'currentTime');
|
||||
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
|
||||
@ -233,13 +231,13 @@ async_test(function(t) {
|
||||
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
return animation.ready.then(function() {
|
||||
checkStateOnReadyPromiseResolved(animation);
|
||||
|
||||
animation.currentTime =
|
||||
currentTimeForStartOfActiveInterval(animation.timeline);
|
||||
return eventWatcher.wait_for('animationstart');
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
checkStateAtActiveIntervalStartTime(animation);
|
||||
|
||||
animation.currentTime =
|
||||
@ -249,17 +247,13 @@ async_test(function(t) {
|
||||
animation.currentTime =
|
||||
currentTimeForEndOfActiveInterval(animation.timeline);
|
||||
return eventWatcher.wait_for('animationend');
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
checkStateAtActiveIntervalEndTime(animation);
|
||||
})).catch(t.step_func(function(reason) {
|
||||
assert_unreached(reason);
|
||||
})).then(function() {
|
||||
t.done();
|
||||
});
|
||||
}, 'Skipping forward through animation');
|
||||
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
|
||||
@ -278,8 +272,8 @@ async_test(function(t) {
|
||||
// an 'animationend' event. We need to wait for these events before we start
|
||||
// testing going backwards since EventWatcher will fail the test if it gets
|
||||
// an event that we haven't told it about.
|
||||
eventWatcher.wait_for(['animationstart',
|
||||
'animationend']).then(t.step_func(function() {
|
||||
var retPromise = eventWatcher.wait_for(['animationstart',
|
||||
'animationend']).then(function() {
|
||||
assert_true(document.timeline.currentTime - previousTimelineTime <
|
||||
ANIM_DUR_MS,
|
||||
'Sanity check that seeking worked rather than the events ' +
|
||||
@ -304,7 +298,7 @@ async_test(function(t) {
|
||||
var promise = eventWatcher.wait_for('animationstart');
|
||||
checkStateAtFiftyPctOfActiveInterval(animation);
|
||||
return promise;
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
animation.currentTime =
|
||||
currentTimeForStartOfActiveInterval(animation.timeline);
|
||||
checkStateAtActiveIntervalStartTime(animation);
|
||||
@ -314,21 +308,16 @@ async_test(function(t) {
|
||||
// the animation start time, we now expect an animationend event
|
||||
// because we went from inside to outside the active interval.
|
||||
return eventWatcher.wait_for('animationend');
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
checkStateOnReadyPromiseResolved(animation);
|
||||
})).catch(t.step_func(function(reason) {
|
||||
assert_unreached(reason);
|
||||
})).then(function() {
|
||||
t.done();
|
||||
});
|
||||
|
||||
// This must come after we've set up the Promise chain, since requesting
|
||||
// computed style will force events to be dispatched.
|
||||
// XXX For some reason this fails occasionally (either the animation.playState
|
||||
// check or the marginLeft check).
|
||||
//checkStateAtActiveIntervalEndTime(animation);
|
||||
}, 'Skipping backwards through animation');
|
||||
checkStateAtActiveIntervalEndTime(animation);
|
||||
|
||||
return retPromise;
|
||||
}, 'Skipping backwards through animation');
|
||||
|
||||
// Next we have multiple tests to check that redundant currentTime changes do
|
||||
// NOT dispatch events. It's impossible to distinguish between events not being
|
||||
@ -339,7 +328,7 @@ async_test(function(t) {
|
||||
// have happened, then assume that no events will ever be dispatched for the
|
||||
// redundant changes if no events were detected in that time.
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
@ -348,12 +337,10 @@ async_test(function(t) {
|
||||
animation.currentTime = currentTimeForActivePhase(animation.timeline);
|
||||
animation.currentTime = currentTimeForBeforePhase(animation.timeline);
|
||||
|
||||
waitForAnimationFrames(2).then(function() {
|
||||
t.done();
|
||||
});
|
||||
return waitForAnimationFrames(2);
|
||||
}, 'Redundant change, before -> active, then back');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
@ -362,86 +349,84 @@ async_test(function(t) {
|
||||
animation.currentTime = currentTimeForAfterPhase(animation.timeline);
|
||||
animation.currentTime = currentTimeForBeforePhase(animation.timeline);
|
||||
|
||||
waitForAnimationFrames(2).then(function() {
|
||||
t.done();
|
||||
});
|
||||
return waitForAnimationFrames(2);
|
||||
}, 'Redundant change, before -> after, then back');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
eventWatcher.wait_for('animationstart').then(function() {
|
||||
var retPromise = eventWatcher.wait_for('animationstart').then(function() {
|
||||
animation.currentTime = currentTimeForBeforePhase(animation.timeline);
|
||||
animation.currentTime = currentTimeForActivePhase(animation.timeline);
|
||||
|
||||
waitForAnimationFrames(2).then(function() {
|
||||
t.done();
|
||||
});
|
||||
return waitForAnimationFrames(2);
|
||||
});
|
||||
// get us into the initial state:
|
||||
animation.currentTime = currentTimeForActivePhase(animation.timeline);
|
||||
|
||||
return retPromise;
|
||||
}, 'Redundant change, active -> before, then back');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
eventWatcher.wait_for('animationstart').then(function() {
|
||||
var retPromise = eventWatcher.wait_for('animationstart').then(function() {
|
||||
animation.currentTime = currentTimeForAfterPhase(animation.timeline);
|
||||
animation.currentTime = currentTimeForActivePhase(animation.timeline);
|
||||
|
||||
waitForAnimationFrames(2).then(function() {
|
||||
t.done();
|
||||
});
|
||||
return waitForAnimationFrames(2);
|
||||
});
|
||||
// get us into the initial state:
|
||||
animation.currentTime = currentTimeForActivePhase(animation.timeline);
|
||||
|
||||
return retPromise;
|
||||
}, 'Redundant change, active -> after, then back');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
eventWatcher.wait_for(['animationstart',
|
||||
'animationend']).then(function() {
|
||||
var retPromise = eventWatcher.wait_for(['animationstart',
|
||||
'animationend']).then(function() {
|
||||
animation.currentTime = currentTimeForBeforePhase(animation.timeline);
|
||||
animation.currentTime = currentTimeForAfterPhase(animation.timeline);
|
||||
|
||||
waitForAnimationFrames(2).then(function() {
|
||||
t.done();
|
||||
});
|
||||
return waitForAnimationFrames(2);
|
||||
});
|
||||
// get us into the initial state:
|
||||
animation.currentTime = currentTimeForAfterPhase(animation.timeline);
|
||||
|
||||
return retPromise;
|
||||
}, 'Redundant change, after -> before, then back');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
eventWatcher.wait_for(['animationstart',
|
||||
'animationend']).then(function() {
|
||||
var retPromise = eventWatcher.wait_for(['animationstart',
|
||||
'animationend']).then(function() {
|
||||
animation.currentTime = currentTimeForActivePhase(animation.timeline);
|
||||
animation.currentTime = currentTimeForAfterPhase(animation.timeline);
|
||||
|
||||
waitForAnimationFrames(2).then(function() {
|
||||
t.done();
|
||||
});
|
||||
return waitForAnimationFrames(2);
|
||||
});
|
||||
// get us into the initial state:
|
||||
animation.currentTime = currentTimeForAfterPhase(animation.timeline);
|
||||
|
||||
return retPromise;
|
||||
}, 'Redundant change, after -> active, then back');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
@ -450,23 +435,20 @@ async_test(function(t) {
|
||||
animation.pause();
|
||||
animation.currentTime = currentTimeForAfterPhase(animation.timeline);
|
||||
|
||||
eventWatcher.wait_for(['animationstart',
|
||||
'animationend']).then(t.step_func(function() {
|
||||
return eventWatcher.wait_for(['animationstart',
|
||||
'animationend']).then(function() {
|
||||
animation.currentTime = currentTimeForActivePhase(animation.timeline);
|
||||
return eventWatcher.wait_for('animationstart');
|
||||
})).then(t.step_func(function() {
|
||||
t.done();
|
||||
}));
|
||||
|
||||
});
|
||||
}, 'Seeking finished -> paused dispatches animationstart');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
return animation.ready.then(function() {
|
||||
var exception;
|
||||
try {
|
||||
animation.currentTime = null;
|
||||
@ -476,65 +458,55 @@ async_test(function(t) {
|
||||
assert_equals(exception.name, 'TypeError',
|
||||
'Expect TypeError exception on trying to set ' +
|
||||
'Animation.currentTime to null');
|
||||
})).catch(t.step_func(function(reason) {
|
||||
assert_unreached(reason);
|
||||
})).then(function() {
|
||||
t.done();
|
||||
});
|
||||
}, 'Setting currentTime to null');
|
||||
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
div.style.animation = 'anim 100s';
|
||||
|
||||
var animation = div.getAnimations()[0];
|
||||
var pauseTime;
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
return animation.ready.then(function() {
|
||||
assert_not_equals(animation.currentTime, null,
|
||||
'Animation.currentTime not null on ready Promise resolve');
|
||||
animation.pause();
|
||||
return animation.ready;
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
pauseTime = animation.currentTime;
|
||||
return waitForFrame();
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
assert_equals(animation.currentTime, pauseTime,
|
||||
'Animation.currentTime is unchanged after pausing');
|
||||
})).catch(t.step_func(function(reason) {
|
||||
assert_unreached(reason);
|
||||
})).then(function() {
|
||||
t.done();
|
||||
});
|
||||
}, 'Animation.currentTime after pausing');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(function() {
|
||||
return animation.ready.then(function() {
|
||||
// just before animation ends:
|
||||
animation.currentTime = ANIM_DELAY_MS + ANIM_DUR_MS - 1;
|
||||
|
||||
return waitForAnimationFrames(2);
|
||||
}).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
assert_equals(animation.currentTime, ANIM_DELAY_MS + ANIM_DUR_MS,
|
||||
'Animation.currentTime should not continue to increase after the ' +
|
||||
'animation has finished');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'Animation.currentTime clamping');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(function() {
|
||||
return animation.ready.then(function() {
|
||||
// play backwards:
|
||||
animation.playbackRate = -1;
|
||||
|
||||
@ -542,12 +514,11 @@ async_test(function(t) {
|
||||
animation.currentTime = 1;
|
||||
|
||||
return waitForAnimationFrames(2);
|
||||
}).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
assert_equals(animation.currentTime, 0,
|
||||
'Animation.currentTime should not continue to decrease after an ' +
|
||||
'animation running in reverse has finished and currentTime is zero');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'Animation.currentTime clamping for reversed animation');
|
||||
|
||||
test(function(t) {
|
||||
@ -560,12 +531,12 @@ test(function(t) {
|
||||
'The currentTime of a cancelled animation should be null');
|
||||
}, 'Animation.currentTime after cancelling');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
div.style.animation = 'anim 100s';
|
||||
|
||||
var animation = div.getAnimations()[0];
|
||||
animation.ready.then(t.step_func(function() {
|
||||
return animation.ready.then(function() {
|
||||
animation.finish();
|
||||
|
||||
// Initiate a pause then abort it
|
||||
@ -574,12 +545,11 @@ async_test(function(t) {
|
||||
|
||||
// Wait to return to running state
|
||||
return animation.ready;
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
assert_true(animation.currentTime < 100 * 1000,
|
||||
'After aborting a pause when finished, the currentTime should'
|
||||
+ ' jump back towards the start of the animation');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'After aborting a pause when finished, the call to play() should rewind'
|
||||
+ ' the current time');
|
||||
|
||||
|
@ -12,204 +12,35 @@
|
||||
'use strict';
|
||||
|
||||
const ANIM_PROP_VAL = 'abc 100s';
|
||||
const ANIM_DURATION = 100000; // ms
|
||||
const ANIM_DURATION = 100 * MS_PER_SEC;
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
var previousFinishedPromise = animation.finished;
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
assert_equals(animation.finished, previousFinishedPromise,
|
||||
'Finished promise is the same object when playing starts');
|
||||
animation.pause();
|
||||
assert_equals(animation.finished, previousFinishedPromise,
|
||||
'Finished promise does not change when pausing');
|
||||
animation.play();
|
||||
assert_equals(animation.finished, previousFinishedPromise,
|
||||
'Finished promise does not change when play() unpauses');
|
||||
|
||||
animation.currentTime = ANIM_DURATION;
|
||||
|
||||
return animation.finished;
|
||||
})).then(t.step_func(function() {
|
||||
assert_equals(animation.finished, previousFinishedPromise,
|
||||
'Finished promise is the same object when playing completes');
|
||||
t.done();
|
||||
}));
|
||||
}, 'Test pausing then playing does not change the finished promise');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
var previousFinishedPromise = animation.finished;
|
||||
|
||||
animation.finish();
|
||||
|
||||
animation.finished.then(t.step_func(function() {
|
||||
assert_equals(animation.finished, previousFinishedPromise,
|
||||
'Finished promise is the same object when playing completes');
|
||||
animation.play();
|
||||
assert_not_equals(animation.finished, previousFinishedPromise,
|
||||
'Finished promise changes when replaying animation');
|
||||
|
||||
previousFinishedPromise = animation.finished;
|
||||
animation.play();
|
||||
assert_equals(animation.finished, previousFinishedPromise,
|
||||
'Finished promise is the same after redundant play() call');
|
||||
|
||||
t.done();
|
||||
}));
|
||||
}, 'Test restarting a finished animation');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
var previousFinishedPromise;
|
||||
|
||||
animation.finish();
|
||||
|
||||
animation.finished.then(t.step_func(function() {
|
||||
previousFinishedPromise = animation.finished;
|
||||
animation.playbackRate = -1;
|
||||
assert_not_equals(animation.finished, previousFinishedPromise,
|
||||
'Finished promise should be replaced when reversing a ' +
|
||||
'finished promise');
|
||||
animation.currentTime = 0;
|
||||
return animation.finished;
|
||||
})).then(t.step_func(function() {
|
||||
previousFinishedPromise = animation.finished;
|
||||
animation.play();
|
||||
assert_not_equals(animation.finished, previousFinishedPromise,
|
||||
'Finished promise is replaced after play() call on ' +
|
||||
'finished, reversed animation');
|
||||
t.done();
|
||||
}));
|
||||
}, 'Test restarting a reversed finished animation');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
var previousFinishedPromise = animation.finished;
|
||||
|
||||
animation.finish();
|
||||
|
||||
animation.finished.then(t.step_func(function() {
|
||||
animation.currentTime = ANIM_DURATION + 1000;
|
||||
assert_equals(animation.finished, previousFinishedPromise,
|
||||
'Finished promise is unchanged jumping past end of ' +
|
||||
'finished animation');
|
||||
|
||||
t.done();
|
||||
}));
|
||||
}, 'Test redundant finishing of animation');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
// Setup callback to run if finished promise is resolved
|
||||
var finishPromiseResolved = false;
|
||||
animation.finished.then(function() {
|
||||
finishPromiseResolved = true;
|
||||
});
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
// Jump to mid-way in interval and pause
|
||||
animation.currentTime = ANIM_DURATION / 2;
|
||||
animation.pause();
|
||||
return animation.ready;
|
||||
})).then(t.step_func(function() {
|
||||
// Jump to the end
|
||||
// (But don't use finish() since that should unpause as well)
|
||||
animation.currentTime = ANIM_DURATION;
|
||||
return waitForAnimationFrames(2);
|
||||
})).then(t.step_func(function() {
|
||||
assert_false(finishPromiseResolved,
|
||||
'Finished promise should not resolve when paused');
|
||||
t.done();
|
||||
}));
|
||||
}, 'Finished promise does not resolve when paused');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
// Setup callback to run if finished promise is resolved
|
||||
var finishPromiseResolved = false;
|
||||
animation.finished.then(function() {
|
||||
finishPromiseResolved = true;
|
||||
});
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
// Jump to mid-way in interval and pause
|
||||
animation.currentTime = ANIM_DURATION / 2;
|
||||
animation.pause();
|
||||
// Jump to the end
|
||||
animation.currentTime = ANIM_DURATION;
|
||||
return waitForAnimationFrames(2);
|
||||
})).then(t.step_func(function() {
|
||||
assert_false(finishPromiseResolved,
|
||||
'Finished promise should not resolve when pause-pending');
|
||||
t.done();
|
||||
}));
|
||||
}, 'Finished promise does not resolve when pause-pending');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.currentTime = ANIM_DURATION;
|
||||
animation.finished.then(t.step_func(function(resolvedAnimation) {
|
||||
assert_equals(resolvedAnimation, animation,
|
||||
'Object identity of animation passed to Promise callback'
|
||||
+ ' matches the animation object owning the Promise');
|
||||
t.done();
|
||||
}));
|
||||
}, 'The finished promise is fulfilled with its Animation');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
|
||||
// Set up pending animation
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
var previousFinishedPromise = animation.finished;
|
||||
|
||||
// Set up listeners on finished promise
|
||||
animation.finished.then(t.step_func(function() {
|
||||
var retPromise = animation.finished.then(function() {
|
||||
assert_unreached('finished promise is fulfilled');
|
||||
})).catch(t.step_func(function(err) {
|
||||
}).catch(function(err) {
|
||||
assert_equals(err.name, 'AbortError',
|
||||
'finished promise is rejected with AbortError');
|
||||
assert_not_equals(animation.finished, previousFinishedPromise,
|
||||
'Finished promise should change after the original is ' +
|
||||
'rejected');
|
||||
})).then(t.step_func(function() {
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
|
||||
// Now cancel the animation and flush styles
|
||||
div.style.animation = '';
|
||||
window.getComputedStyle(div).animation;
|
||||
|
||||
return retPromise;
|
||||
}, 'finished promise is rejected when an animation is cancelled by resetting ' +
|
||||
'the animation property');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
|
||||
// As before, but this time instead of removing all animations, simply update
|
||||
// the list of animations. At least for Firefox, updating is a different
|
||||
// code path.
|
||||
@ -220,327 +51,43 @@ async_test(function(t) {
|
||||
var previousFinishedPromise = animation.finished;
|
||||
|
||||
// Set up listeners on finished promise
|
||||
animation.finished.then(t.step_func(function() {
|
||||
var retPromise = animation.finished.then(function() {
|
||||
assert_unreached('finished promise was fulfilled');
|
||||
})).catch(t.step_func(function(err) {
|
||||
}).catch(function(err) {
|
||||
assert_equals(err.name, 'AbortError',
|
||||
'finished promise is rejected with AbortError');
|
||||
assert_not_equals(animation.finished, previousFinishedPromise,
|
||||
'Finished promise should change after the original is ' +
|
||||
'rejected');
|
||||
})).then(t.step_func(function() {
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
|
||||
// Now update the animation and flush styles
|
||||
div.style.animation = 'def 100s';
|
||||
window.getComputedStyle(div).animation;
|
||||
|
||||
return retPromise;
|
||||
}, 'finished promise is rejected when an animation is cancelled by changing ' +
|
||||
'the animation property');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
var previousFinishedPromise = animation.finished;
|
||||
|
||||
// Set up listeners on finished promise
|
||||
animation.finished.then(t.step_func(function() {
|
||||
assert_unreached('finished promise was fulfilled');
|
||||
})).catch(t.step_func(function(err) {
|
||||
assert_equals(err.name, 'AbortError',
|
||||
'finished promise is rejected with AbortError');
|
||||
assert_not_equals(animation.finished, previousFinishedPromise,
|
||||
'Finished promise should change after the original is ' +
|
||||
'rejected');
|
||||
})).then(t.step_func(function() {
|
||||
t.done();
|
||||
}));
|
||||
|
||||
animation.cancel();
|
||||
|
||||
}, 'finished promise is rejected when an animation is cancelled by calling ' +
|
||||
'cancel()');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
var previousFinishedPromise = animation.finished;
|
||||
|
||||
animation.currentTime = ANIM_DURATION;
|
||||
|
||||
animation.finished.then(t.step_func(function() {
|
||||
animation.cancel();
|
||||
assert_not_equals(animation.finished, previousFinishedPromise,
|
||||
'A new finished promise should be created when'
|
||||
+ ' cancelling a finished animation');
|
||||
})).then(t.step_func(function() {
|
||||
t.done();
|
||||
}));
|
||||
}, 'cancelling an already-finished animation replaces the finished promise');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
animation.cancel();
|
||||
|
||||
// The spec says we still create a new finished promise and reject the old
|
||||
// one even if we're already idle. That behavior might change, but for now
|
||||
// test that we do that.
|
||||
animation.finished.catch(t.step_func(function(err) {
|
||||
assert_equals(err.name, 'AbortError',
|
||||
'finished promise is rejected with AbortError');
|
||||
t.done();
|
||||
}));
|
||||
|
||||
// Redundant call to cancel();
|
||||
var previousFinishedPromise = animation.finished;
|
||||
animation.cancel();
|
||||
assert_not_equals(animation.finished, previousFinishedPromise,
|
||||
'A redundant call to cancel() should still generate a new'
|
||||
+ ' finished promise');
|
||||
}, 'cancelling an idle animation still replaces the finished promise');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
const HALF_DUR = ANIM_DURATION / 2;
|
||||
const QUARTER_DUR = ANIM_DURATION / 4;
|
||||
|
||||
var gotNextFrame = false;
|
||||
var currentTimeBeforeShortening;
|
||||
|
||||
animation.currentTime = HALF_DUR;
|
||||
animation.ready.then(t.step_func(function() {
|
||||
currentTimeBeforeShortening = animation.currentTime;
|
||||
|
||||
div.style.animationDuration = QUARTER_DUR + 'ms';
|
||||
window.getComputedStyle(div).animationDuration; // flush style
|
||||
// Animation should now be finished
|
||||
|
||||
// Below we use gotNextFrame to check that shortening of the animation
|
||||
// duration causes the finished promise to resolve, rather than it just
|
||||
// getting resolved on the next animation frame. This relies on the fact
|
||||
// that the promises are resolved as a micro-task before the next frame
|
||||
// happens.
|
||||
|
||||
waitForFrame().then(function() {
|
||||
gotNextFrame = true;
|
||||
});
|
||||
|
||||
return animation.finished;
|
||||
})).then(t.step_func(function() {
|
||||
assert_false(gotNextFrame, 'shortening of the animation duration should ' +
|
||||
'resolve the finished promise');
|
||||
assert_equals(animation.currentTime, currentTimeBeforeShortening,
|
||||
'currentTime should be unchanged when duration shortened');
|
||||
var previousFinishedPromise = animation.finished;
|
||||
div.style.animationDuration = ANIM_DURATION + 'ms'; // now active again
|
||||
window.getComputedStyle(div).animationDuration; // flush style
|
||||
assert_not_equals(animation.finished, previousFinishedPromise,
|
||||
'Finished promise should change after lengthening the ' +
|
||||
'duration causes the animation to become active');
|
||||
t.done();
|
||||
}));
|
||||
}, 'Test finished promise changes for animation duration changes');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(function() {
|
||||
animation.playbackRate = 0;
|
||||
animation.currentTime = ANIM_DURATION + 1000;
|
||||
return waitForAnimationFrames(2);
|
||||
}).then(t.step_func(function() {
|
||||
t.done();
|
||||
}));
|
||||
|
||||
animation.finished.then(t.step_func(function() {
|
||||
assert_unreached('finished promise should not resolve when playbackRate ' +
|
||||
'is zero');
|
||||
}));
|
||||
}, 'Test finished promise changes when playbackRate == 0');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(function() {
|
||||
animation.playbackRate = -1;
|
||||
return animation.finished;
|
||||
}).then(t.step_func(function() {
|
||||
t.done();
|
||||
}));
|
||||
}, 'Test finished promise resolves when playbackRate set to a negative value');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
var previousFinishedPromise = animation.finished;
|
||||
|
||||
animation.currentTime = ANIM_DURATION;
|
||||
|
||||
animation.finished.then(function() {
|
||||
return animation.finished.then(function() {
|
||||
div.style.animationPlayState = 'running';
|
||||
return waitForAnimationFrames(2);
|
||||
}).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
assert_equals(animation.finished, previousFinishedPromise,
|
||||
'Should not replay when animation-play-state changes to ' +
|
||||
'"running" on finished animation');
|
||||
assert_equals(animation.currentTime, ANIM_DURATION,
|
||||
'currentTime should not change when animation-play-state ' +
|
||||
'changes to "running" on finished animation');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'Test finished promise changes when animationPlayState set to running');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
var previousFinishedPromise = animation.finished;
|
||||
|
||||
animation.currentTime = ANIM_DURATION;
|
||||
|
||||
animation.finished.then(t.step_func(function() {
|
||||
animation.currentTime = 0;
|
||||
assert_not_equals(animation.finished, previousFinishedPromise,
|
||||
'Finished promise should change once a prior ' +
|
||||
'finished promise resolved and the animation ' +
|
||||
'falls out finished state');
|
||||
t.done();
|
||||
}));
|
||||
}, 'Test finished promise changes when a prior finished promise resolved ' +
|
||||
'and the animation falls out finished state');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
var previousFinishedPromise = animation.finished;
|
||||
|
||||
animation.currentTime = ANIM_DURATION;
|
||||
animation.currentTime = ANIM_DURATION / 2;
|
||||
|
||||
assert_equals(animation.finished, previousFinishedPromise,
|
||||
'No new finished promise generated when finished state ' +
|
||||
'is checked asynchronously');
|
||||
t.done();
|
||||
}, 'Test no new finished promise generated when finished state ' +
|
||||
'is checked asynchronously');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
var previousFinishedPromise = animation.finished;
|
||||
|
||||
animation.finish();
|
||||
animation.currentTime = ANIM_DURATION / 2;
|
||||
|
||||
assert_not_equals(animation.finished, previousFinishedPromise,
|
||||
'New finished promise generated when finished state ' +
|
||||
'is checked synchronously');
|
||||
t.done();
|
||||
}, 'Test new finished promise generated when finished state ' +
|
||||
'is checked synchronously');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
var resolvedFinished = false;
|
||||
animation.finished.then(function() {
|
||||
resolvedFinished = true;
|
||||
});
|
||||
|
||||
animation.ready.then(function() {
|
||||
animation.finish();
|
||||
animation.currentTime = ANIM_DURATION / 2;
|
||||
}).then(t.step_func(function() {
|
||||
assert_true(resolvedFinished,
|
||||
'Animation.finished should be resolved even if ' +
|
||||
'the finished state is changed soon');
|
||||
t.done();
|
||||
}));
|
||||
|
||||
}, 'Test synchronous finished promise resolved even if finished state ' +
|
||||
'is changed soon');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
var resolvedFinished = false;
|
||||
animation.finished.then(function() {
|
||||
resolvedFinished = true;
|
||||
});
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
animation.currentTime = ANIM_DURATION;
|
||||
animation.finish();
|
||||
})).then(t.step_func(function() {
|
||||
assert_true(resolvedFinished,
|
||||
'Animation.finished should be resolved soon after finish() is ' +
|
||||
'called even if there are other asynchronous promises just before it');
|
||||
t.done();
|
||||
}));
|
||||
}, 'Test synchronous finished promise resolved even if asynchronous ' +
|
||||
'finished promise happens just before synchronous promise');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.finished.then(t.step_func(function() {
|
||||
assert_unreached('Animation.finished should not be resolved');
|
||||
}));
|
||||
|
||||
animation.ready.then(function() {
|
||||
animation.currentTime = ANIM_DURATION;
|
||||
animation.currentTime = ANIM_DURATION / 2;
|
||||
}).then(t.step_func(function() {
|
||||
t.done();
|
||||
}));
|
||||
}, 'Test finished promise is not resolved when the animation ' +
|
||||
'falls out finished state immediately');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = ANIM_PROP_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(function() {
|
||||
animation.currentTime = ANIM_DURATION;
|
||||
animation.finished.then(t.step_func(function() {
|
||||
assert_unreached('Animation.finished should not be resolved');
|
||||
}));
|
||||
animation.currentTime = 0;
|
||||
}).then(t.step_func(function() {
|
||||
t.done();
|
||||
}));
|
||||
|
||||
}, 'Test finished promise is not resolved once the animation ' +
|
||||
'falls out finished state even though the current finished ' +
|
||||
'promise is generated soon after animation state became finished');
|
||||
|
||||
done();
|
||||
</script>
|
||||
</body>
|
||||
|
@ -8,19 +8,24 @@
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
|
||||
test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = 'abc 100s';
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
assert_equals(animation.id, '', 'id for CSS Animation is initially empty');
|
||||
|
||||
animation.id = 'anim'
|
||||
|
||||
assert_equals(animation.id, 'anim', 'animation.id reflects the value set');
|
||||
}, 'Animation.id for CSS Animations');
|
||||
}, 'Animation.id for CSS Animations');
|
||||
|
||||
test(function(t) {
|
||||
var div = addDiv(t);
|
||||
var animation = div.animate({}, 100 * MS_PER_SEC);
|
||||
assert_equals(animation.id, '', 'id for CSS Animation is initially empty');
|
||||
animation.id = 'anim'
|
||||
|
||||
assert_equals(animation.id, 'anim', 'animation.id reflects the value set');
|
||||
}, 'Animation.id for CSS Animations');
|
||||
done();
|
||||
</script>
|
||||
</body>
|
||||
|
@ -15,37 +15,25 @@ function getMarginLeft(cs) {
|
||||
return parseFloat(cs.marginLeft);
|
||||
}
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
var cs = window.getComputedStyle(div);
|
||||
div.style.animation = 'anim 1000s';
|
||||
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
assert_equals(getMarginLeft(cs), 0,
|
||||
'Initial value of margin-left is zero');
|
||||
var previousAnimVal = getMarginLeft(cs);
|
||||
|
||||
animation.ready.then(waitForFrame).then(t.step_func(function() {
|
||||
assert_true(getMarginLeft(cs) > previousAnimVal,
|
||||
'margin-left is initially increasing');
|
||||
animation.pause();
|
||||
return animation.ready;
|
||||
})).then(t.step_func(function() {
|
||||
previousAnimVal = getMarginLeft(cs);
|
||||
return waitForFrame();
|
||||
})).then(t.step_func(function() {
|
||||
assert_equals(getMarginLeft(cs), previousAnimVal,
|
||||
'margin-left does not increase after calling pause()');
|
||||
t.done();
|
||||
}));
|
||||
}, 'pause() a running animation');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
var cs = window.getComputedStyle(div);
|
||||
div.style.animation = 'anim 1000s paused';
|
||||
var animation = div.getAnimations()[0];
|
||||
assert_equals(getMarginLeft(cs), 0,
|
||||
'Initial value of margin-left is zero');
|
||||
animation.play();
|
||||
|
||||
return animation.ready.then(waitForFrame).then(function() {
|
||||
assert_true(getMarginLeft(cs) > 0,
|
||||
'Playing value of margin-left is greater than zero');
|
||||
});
|
||||
}, 'play() overrides animation-play-state');
|
||||
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
var cs = window.getComputedStyle(div);
|
||||
div.style.animation = 'anim 1000s paused';
|
||||
var animation = div.getAnimations()[0];
|
||||
assert_equals(getMarginLeft(cs), 0,
|
||||
'Initial value of margin-left is zero');
|
||||
@ -53,74 +41,49 @@ async_test(function(t) {
|
||||
animation.pause();
|
||||
div.style.animationPlayState = 'running';
|
||||
|
||||
animation.ready.then(waitForFrame).then(t.step_func(function() {
|
||||
return animation.ready.then(waitForFrame).then(function() {
|
||||
assert_equals(cs.animationPlayState, 'running',
|
||||
'animation-play-state is running');
|
||||
assert_equals(getMarginLeft(cs), 0,
|
||||
'Paused value of margin-left is zero');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'pause() overrides animation-play-state');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
var cs = window.getComputedStyle(div);
|
||||
div.style.animation = 'anim 1000s paused';
|
||||
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
assert_equals(getMarginLeft(cs), 0,
|
||||
'Initial value of margin-left is zero');
|
||||
|
||||
animation.play();
|
||||
|
||||
animation.ready.then(waitForFrame).then(t.step_func(function() {
|
||||
assert_true(getMarginLeft(cs) > 0,
|
||||
'Playing value of margin-left is greater than zero');
|
||||
t.done();
|
||||
}));
|
||||
}, 'play() overrides animation-play-state');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
var cs = window.getComputedStyle(div);
|
||||
div.style.animation = 'anim 1000s paused';
|
||||
|
||||
var animation = div.getAnimations()[0];
|
||||
assert_equals(getMarginLeft(cs), 0,
|
||||
'Initial value of margin-left is zero');
|
||||
|
||||
animation.play();
|
||||
|
||||
var previousAnimVal;
|
||||
|
||||
animation.ready.then(function() {
|
||||
return animation.ready.then(function() {
|
||||
div.style.animationPlayState = 'running';
|
||||
cs.animationPlayState; // Trigger style resolution
|
||||
return waitForFrame();
|
||||
}).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
assert_equals(cs.animationPlayState, 'running',
|
||||
'animation-play-state is running');
|
||||
div.style.animationPlayState = 'paused';
|
||||
return animation.ready;
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
assert_equals(cs.animationPlayState, 'paused',
|
||||
'animation-play-state is paused');
|
||||
previousAnimVal = getMarginLeft(cs);
|
||||
return waitForFrame();
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
assert_equals(getMarginLeft(cs), previousAnimVal,
|
||||
'Animated value of margin-left does not change when'
|
||||
+ ' paused by style');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'play() is overridden by later setting "animation-play-state: paused"');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
var cs = window.getComputedStyle(div);
|
||||
div.style.animation = 'anim 1000s';
|
||||
|
||||
var animation = div.getAnimations()[0];
|
||||
assert_equals(getMarginLeft(cs), 0,
|
||||
'Initial value of margin-left is zero');
|
||||
@ -132,20 +95,18 @@ async_test(function(t) {
|
||||
animation.play();
|
||||
var previousAnimVal = getMarginLeft(cs);
|
||||
|
||||
animation.ready.then(waitForFrame).then(t.step_func(function() {
|
||||
return animation.ready.then(waitForFrame).then(function() {
|
||||
assert_equals(cs.animationPlayState, 'paused',
|
||||
'animation-play-state is paused');
|
||||
assert_true(getMarginLeft(cs) > previousAnimVal,
|
||||
'Playing value of margin-left is increasing');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'play() flushes pending changes to animation-play-state first');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
var cs = window.getComputedStyle(div);
|
||||
div.style.animation = 'anim 1000s paused';
|
||||
|
||||
var animation = div.getAnimations()[0];
|
||||
assert_equals(getMarginLeft(cs), 0,
|
||||
'Initial value of margin-left is zero');
|
||||
@ -164,112 +125,41 @@ async_test(function(t) {
|
||||
animation.pause();
|
||||
var previousAnimVal = getMarginLeft(cs);
|
||||
|
||||
animation.ready.then(waitForFrame).then(t.step_func(function() {
|
||||
return animation.ready.then(waitForFrame).then(function() {
|
||||
assert_equals(cs.animationPlayState, 'running',
|
||||
'animation-play-state is running');
|
||||
assert_equals(getMarginLeft(cs), previousAnimVal,
|
||||
'Paused value of margin-left does not change');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'pause() applies pending changes to animation-play-state first');
|
||||
// (Note that we can't actually test for this; see comment above, in test-body.)
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 1000s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
var readyPromiseRun = false;
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
return animation.ready.then(function() {
|
||||
div.style.animationPlayState = 'paused';
|
||||
assert_equals(animation.playState, 'pending', 'Animation is pause pending');
|
||||
|
||||
// Set current time
|
||||
animation.currentTime = 5000;
|
||||
animation.currentTime = 5 * MS_PER_SEC;
|
||||
assert_equals(animation.playState, 'paused',
|
||||
'Animation is paused immediately after setting currentTime');
|
||||
assert_equals(animation.startTime, null,
|
||||
'Animation startTime is unresolved immediately after ' +
|
||||
'setting currentTime');
|
||||
assert_equals(animation.currentTime, 5000,
|
||||
assert_equals(animation.currentTime, 5 * MS_PER_SEC,
|
||||
'Animation currentTime does not change when forcing a ' +
|
||||
'pause operation to complete');
|
||||
|
||||
// The ready promise should now be resolved. If it's not then test will
|
||||
// probably time out before anything else happens that causes it to resolve.
|
||||
return animation.ready;
|
||||
})).then(t.step_func(function() {
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'Setting the current time completes a pending pause');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 1000s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
// Go to idle state then pause
|
||||
animation.cancel();
|
||||
animation.pause();
|
||||
|
||||
assert_equals(animation.currentTime, 0, 'currentTime is set to 0');
|
||||
assert_equals(animation.startTime, null, 'startTime is not set');
|
||||
assert_equals(animation.playState, 'pending', 'initially pause-pending');
|
||||
|
||||
// Check it still resolves as expected
|
||||
animation.ready.then(t.step_func(function() {
|
||||
assert_equals(animation.playState, 'paused',
|
||||
'resolves to paused state asynchronously');
|
||||
assert_equals(animation.currentTime, 0,
|
||||
'keeps the initially set currentTime');
|
||||
t.done();
|
||||
}));
|
||||
}, 'pause() from idle');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 1000s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.cancel();
|
||||
animation.playbackRate = -1;
|
||||
animation.pause();
|
||||
|
||||
assert_equals(animation.currentTime, 1000 * 1000,
|
||||
'currentTime is set to the effect end');
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
assert_equals(animation.currentTime, 1000 * 1000,
|
||||
'keeps the initially set currentTime');
|
||||
t.done();
|
||||
}));
|
||||
}, 'pause() from idle with a negative playbackRate');
|
||||
|
||||
test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 1000s infinite' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.cancel();
|
||||
animation.playbackRate = -1;
|
||||
|
||||
assert_throws('InvalidStateError',
|
||||
function () { animation.pause(); },
|
||||
'Expect InvalidStateError exception on calling pause() ' +
|
||||
'from idle with a negative playbackRate and ' +
|
||||
'infinite-duration animation');
|
||||
}, 'pause() from idle with a negative playbackRate and endless effect');
|
||||
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 1000s' });
|
||||
return div.getAnimations()[0].ready
|
||||
.then(function(animation) {
|
||||
animation.finish();
|
||||
animation.pause();
|
||||
return animation.ready;
|
||||
}).then(function(animation) {
|
||||
assert_equals(animation.currentTime, 1000 * 1000,
|
||||
'currentTime after pausing finished animation');
|
||||
});
|
||||
}, 'pause() on a finished animation');
|
||||
|
||||
done();
|
||||
</script>
|
||||
</body>
|
||||
|
@ -10,76 +10,21 @@
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = 'abc 100s';
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
var originalReadyPromise = animation.ready;
|
||||
var pauseReadyPromise;
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
assert_equals(animation.ready, originalReadyPromise,
|
||||
'Ready promise is the same object when playing completes');
|
||||
animation.pause();
|
||||
assert_not_equals(animation.ready, originalReadyPromise,
|
||||
'A new ready promise is created when pausing');
|
||||
pauseReadyPromise = animation.ready;
|
||||
// Wait for the promise to fulfill since if we abort the pause the ready
|
||||
// promise object is reused.
|
||||
return animation.ready;
|
||||
})).then(t.step_func(function() {
|
||||
animation.play();
|
||||
assert_not_equals(animation.ready, pauseReadyPromise,
|
||||
'A new ready promise is created when playing');
|
||||
t.done();
|
||||
}));
|
||||
}, 'A new ready promise is created when play()/pause() is called');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = 'abc 100s paused';
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
var originalReadyPromise = animation.ready;
|
||||
animation.ready.then(t.step_func(function() {
|
||||
|
||||
return animation.ready.then(function() {
|
||||
div.style.animationPlayState = 'running';
|
||||
assert_not_equals(animation.ready, originalReadyPromise,
|
||||
'After updating animation-play-state a new ready promise'
|
||||
+ ' object is created');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'A new ready promise is created when setting animation-play-state: running');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = 'abc 100s';
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
var promiseBeforeCallingPlay = animation.ready;
|
||||
animation.play();
|
||||
assert_equals(animation.ready, promiseBeforeCallingPlay,
|
||||
'Ready promise has same object identity after redundant call'
|
||||
+ ' to play()');
|
||||
t.done();
|
||||
}));
|
||||
}, 'Redundant calls to play() do not generate new ready promise objects');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = 'abc 100s';
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(t.step_func(function(resolvedAnimation) {
|
||||
assert_equals(resolvedAnimation, animation,
|
||||
'Object identity of Animation passed to Promise callback'
|
||||
+ ' matches the Animation object owning the Promise');
|
||||
t.done();
|
||||
}));
|
||||
}, 'The ready promise is fulfilled with its Animation');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
|
||||
// Set up pending animation
|
||||
@ -89,23 +34,22 @@ async_test(function(t) {
|
||||
'Animation is initially pending');
|
||||
|
||||
// Set up listeners on ready promise
|
||||
animation.ready.then(t.step_func(function() {
|
||||
var retPromise = animation.ready.then(function() {
|
||||
assert_unreached('ready promise is fulfilled');
|
||||
})).catch(t.step_func(function(err) {
|
||||
}).catch(function(err) {
|
||||
assert_equals(err.name, 'AbortError',
|
||||
'ready promise is rejected with AbortError');
|
||||
})).then(t.step_func(function() {
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
|
||||
// Now cancel the animation and flush styles
|
||||
div.style.animation = '';
|
||||
window.getComputedStyle(div).animation;
|
||||
|
||||
return retPromise;
|
||||
}, 'ready promise is rejected when an animation is cancelled by resetting'
|
||||
+ ' the animation property');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
|
||||
// As before, but this time instead of removing all animations, simply update
|
||||
@ -119,96 +63,52 @@ async_test(function(t) {
|
||||
'Animation is initially pending');
|
||||
|
||||
// Set up listeners on ready promise
|
||||
animation.ready.then(t.step_func(function() {
|
||||
var retPromise = animation.ready.then(function() {
|
||||
assert_unreached('ready promise was fulfilled');
|
||||
})).catch(t.step_func(function(err) {
|
||||
}).catch(function(err) {
|
||||
assert_equals(err.name, 'AbortError',
|
||||
'ready promise is rejected with AbortError');
|
||||
})).then(t.step_func(function() {
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
|
||||
// Now update the animation and flush styles
|
||||
div.style.animation = 'def 100s';
|
||||
window.getComputedStyle(div).animation;
|
||||
|
||||
return retPromise;
|
||||
}, 'ready promise is rejected when an animation is cancelled by updating'
|
||||
+ ' the animation property');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = 'abc 100s';
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
assert_unreached('ready promise was fulfilled');
|
||||
})).catch(t.step_func(function(err) {
|
||||
assert_equals(err.name, 'AbortError',
|
||||
'ready promise is rejected with AbortError');
|
||||
})).then(t.step_func(function() {
|
||||
t.done();
|
||||
}));
|
||||
|
||||
animation.cancel();
|
||||
}, 'ready promise is rejected when a play-pending animation is cancelled by'
|
||||
+ ' calling cancel()');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = 'abc 100s';
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
animation.pause();
|
||||
|
||||
// Set up listeners on pause-pending ready promise
|
||||
animation.ready.then(t.step_func(function() {
|
||||
assert_unreached('ready promise was fulfilled');
|
||||
})).catch(t.step_func(function(err) {
|
||||
assert_equals(err.name, 'AbortError',
|
||||
'ready promise is rejected with AbortError');
|
||||
})).then(t.step_func(function() {
|
||||
t.done();
|
||||
}));
|
||||
|
||||
animation.cancel();
|
||||
}));
|
||||
}, 'ready promise is rejected when a pause-pending animation is cancelled by'
|
||||
+ ' calling cancel()');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: abc 100s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
var originalReadyPromise = animation.ready;
|
||||
animation.ready.then(t.step_func(function() {
|
||||
|
||||
return animation.ready.then(function() {
|
||||
div.style.animationPlayState = 'paused';
|
||||
assert_not_equals(animation.ready, originalReadyPromise,
|
||||
'A new Promise object is generated when setting'
|
||||
+ ' animation-play-state: paused');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'A new ready promise is created when setting animation-play-state: paused');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: abc 100s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
return animation.ready.then(function() {
|
||||
div.style.animationPlayState = 'paused';
|
||||
var firstReadyPromise = animation.ready;
|
||||
animation.pause();
|
||||
assert_equals(animation.ready, firstReadyPromise,
|
||||
'Ready promise objects are identical after redundant pause');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'Pausing twice re-uses the same Promise');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: abc 100s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
return animation.ready.then(function() {
|
||||
div.style.animationPlayState = 'paused';
|
||||
|
||||
// Flush style and verify we're pending at the same time
|
||||
@ -223,27 +123,25 @@ async_test(function(t) {
|
||||
+ ' to pause');
|
||||
|
||||
return animation.ready;
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
assert_equals(animation.playState, 'running',
|
||||
'Animation is running after aborting a pause');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'If a pause operation is interrupted, the ready promise is reused');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: abc 100s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
return animation.ready.then(function() {
|
||||
div.style.animationPlayState = 'paused';
|
||||
return animation.ready;
|
||||
})).then(t.step_func(function(resolvedAnimation) {
|
||||
}).then(function(resolvedAnimation) {
|
||||
assert_equals(resolvedAnimation, animation,
|
||||
'Promise received when ready Promise for a pause operation'
|
||||
+ ' is completed is the animation on which the pause was'
|
||||
+ ' performed');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'When a pause is complete the Promise callback gets the correct animation');
|
||||
|
||||
done();
|
||||
|
@ -10,38 +10,7 @@
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 100s infinite' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
// Wait a frame because if currentTime is still 0 when we call
|
||||
// reverse(), it will throw (per spec).
|
||||
animation.ready.then(waitForFrame).then(t.step_func_done(function() {
|
||||
assert_greater_than(animation.currentTime, 0,
|
||||
'currentTime expected to be greater than 0, one frame after starting');
|
||||
var previousPlaybackRate = animation.playbackRate;
|
||||
animation.reverse();
|
||||
assert_equals(animation.playbackRate, -previousPlaybackRate,
|
||||
'playbackRate should be invetrted');
|
||||
}));
|
||||
}, 'reverse() inverts playbackRate');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 100s infinite' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.currentTime = 50000;
|
||||
animation.pause();
|
||||
animation.ready.then(t.step_func(function() {
|
||||
animation.reverse();
|
||||
return animation.ready;
|
||||
})).then(t.step_func_done(function() {
|
||||
assert_equals(animation.playState, 'running',
|
||||
'Animation.playState should be "running" after reverse()');
|
||||
}));
|
||||
}, 'reverse() starts to play when pausing animation');
|
||||
|
||||
async_test(function(t) {
|
||||
test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 100s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
div.style.animation = "";
|
||||
@ -50,123 +19,10 @@ async_test(function(t) {
|
||||
assert_equals(animation.currentTime, null);
|
||||
animation.reverse();
|
||||
|
||||
assert_equals(animation.currentTime, 100000,
|
||||
assert_equals(animation.currentTime, 100 * MS_PER_SEC,
|
||||
'animation.currentTime should be its effect end');
|
||||
t.done();
|
||||
}, 'reverse() from idle state starts playing the animation');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 100s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.currentTime = 50000;
|
||||
animation.reverse();
|
||||
|
||||
assert_equals(animation.currentTime, 50000,
|
||||
'reverse() should not change the currentTime ' +
|
||||
'if the currentTime is in the middle of animation duration');
|
||||
t.done();
|
||||
}, 'reverse() maintains the same currentTime');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 100s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.currentTime = 200000;
|
||||
animation.reverse();
|
||||
|
||||
assert_equals(animation.currentTime, 100000,
|
||||
'reverse() should start playing from the animation effect end ' +
|
||||
'if the playbackRate > 0 and the currentTime > effect end');
|
||||
t.done();
|
||||
}, 'reverse() when playbackRate > 0 and currentTime > effect end');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 100s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.currentTime = -200000;
|
||||
animation.reverse();
|
||||
|
||||
assert_equals(animation.currentTime, 100000,
|
||||
'reverse() should start playing from the animation effect end ' +
|
||||
'if the playbackRate > 0 and the currentTime < 0');
|
||||
t.done();
|
||||
}, 'reverse() when playbackRate > 0 and currentTime < 0');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 100s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.playbackRate = -1;
|
||||
animation.currentTime = -200000;
|
||||
animation.reverse();
|
||||
|
||||
assert_equals(animation.currentTime, 0,
|
||||
'reverse() should start playing from the start of animation time ' +
|
||||
'if the playbackRate < 0 and the currentTime < 0');
|
||||
t.done();
|
||||
}, 'reverse() when playbackRate < 0 and currentTime < 0');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 100s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.playbackRate = -1;
|
||||
animation.currentTime = 200000;
|
||||
animation.reverse();
|
||||
|
||||
assert_equals(animation.currentTime, 0,
|
||||
'reverse() should start playing from the start of animation time ' +
|
||||
'if the playbackRate < 0 and the currentTime > effect end');
|
||||
t.done();
|
||||
}, 'reverse() when playbackRate < 0 and currentTime > effect end');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 100s infinite' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.currentTime = -200000;
|
||||
|
||||
assert_throws('InvalidStateError',
|
||||
function () { animation.reverse(); },
|
||||
'reverse() should throw InvalidStateError ' +
|
||||
'if the playbackRate > 0 and the currentTime < 0 ' +
|
||||
'and the target effect is positive infinity');
|
||||
t.done();
|
||||
}, 'reverse() when playbackRate > 0 and currentTime < 0 ' +
|
||||
'and the target effect is positive infinity');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 100s infinite' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.playbackRate = -1;
|
||||
animation.currentTime = -200000;
|
||||
animation.reverse();
|
||||
|
||||
assert_equals(animation.currentTime, 0,
|
||||
'reverse() should start playing from the start of animation time ' +
|
||||
'if the playbackRate < 0 and the currentTime < 0 ' +
|
||||
'and the target effect is positive infinity');
|
||||
t.done();
|
||||
}, 'reverse() when playbackRate < 0 and currentTime < 0 ' +
|
||||
'and the target effect is positive infinity');
|
||||
|
||||
async_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 100s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.playbackRate = 0;
|
||||
animation.currentTime = 50000;
|
||||
animation.reverse();
|
||||
|
||||
assert_equals(animation.playbackRate, 0,
|
||||
'reverse() should preserve playbackRate if the playbackRate == 0');
|
||||
assert_equals(animation.currentTime, 50000,
|
||||
'reverse() should not affect the currentTime if the playbackRate == 0');
|
||||
t.done();
|
||||
}, 'reverse() when playbackRate == 0');
|
||||
|
||||
done();
|
||||
</script>
|
||||
|
@ -39,8 +39,8 @@
|
||||
|
||||
const CSS_ANIM_EVENTS =
|
||||
['animationstart', 'animationiteration', 'animationend'];
|
||||
const ANIM_DELAY_MS = 1000000; // 1000s
|
||||
const ANIM_DUR_MS = 1000000; // 1000s
|
||||
const ANIM_DELAY_MS = 1000 * MS_PER_SEC; // 1000s
|
||||
const ANIM_DUR_MS = 1000 * MS_PER_SEC; // 1000s
|
||||
const ANIM_PROPERTY_VAL = 'anim ' + ANIM_DUR_MS + 'ms ' + ANIM_DELAY_MS + 'ms';
|
||||
|
||||
/**
|
||||
@ -177,33 +177,31 @@ test(function(t)
|
||||
assert_equals(animation.startTime, null, 'startTime is unresolved');
|
||||
}, 'startTime of a newly created (pause-pending) animation is unresolved');
|
||||
|
||||
async_test(function(t)
|
||||
promise_test(function(t)
|
||||
{
|
||||
var div = addDiv(t, { 'style': 'animation: anim 100s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
animation.ready.then(t.step_func(function() {
|
||||
return animation.ready.then(function() {
|
||||
assert_true(animation.startTime > 0,
|
||||
'startTime is resolved when running');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'startTime is resolved when running');
|
||||
|
||||
async_test(function(t)
|
||||
promise_test(function(t)
|
||||
{
|
||||
var div = addDiv(t, { 'style': 'animation: anim 100s paused' });
|
||||
var animation = div.getAnimations()[0];
|
||||
animation.ready.then(t.step_func(function() {
|
||||
return animation.ready.then(function() {
|
||||
assert_equals(animation.startTime, null,
|
||||
'startTime is unresolved when paused');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'startTime is unresolved when paused');
|
||||
|
||||
async_test(function(t)
|
||||
promise_test(function(t)
|
||||
{
|
||||
var div = addDiv(t, { 'style': 'animation: anim 100s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
animation.ready.then(t.step_func(function() {
|
||||
return animation.ready.then(function() {
|
||||
div.style.animationPlayState = 'paused';
|
||||
getComputedStyle(div).animationPlayState;
|
||||
assert_not_equals(animation.startTime, null,
|
||||
@ -213,21 +211,19 @@ async_test(function(t)
|
||||
getComputedStyle(div).animationPlayState;
|
||||
assert_not_equals(animation.startTime, null,
|
||||
'startTime is preserved when a pause is aborted');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'startTime while pause-pending and play-pending');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, { 'style': 'animation: anim 100s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
// Seek to end to put us in the finished state
|
||||
animation.currentTime = 100 * 1000;
|
||||
animation.ready.then(t.step_func(function() {
|
||||
animation.currentTime = 100 * MS_PER_SEC;
|
||||
return animation.ready.then(function() {
|
||||
// Call play() which puts us back in the running state
|
||||
animation.play();
|
||||
assert_equals(animation.startTime, null, 'startTime is unresolved');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'startTime while play-pending from finished state');
|
||||
|
||||
test(function(t) {
|
||||
@ -239,14 +235,14 @@ test(function(t) {
|
||||
assert_equals(animation.startTime, null, 'startTime is unresolved');
|
||||
}, 'startTime while play-pending from finished state using finish()');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, { style: 'animation: anim 1000s' });
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
assert_equals(animation.startTime, null, 'The initial startTime is null');
|
||||
var initialTimelineTime = document.timeline.currentTime;
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
return animation.ready.then(function() {
|
||||
assert_true(animation.startTime > initialTimelineTime,
|
||||
'After the animation has started, startTime is greater than ' +
|
||||
'the time when it was started');
|
||||
@ -261,12 +257,11 @@ async_test(function(t) {
|
||||
assert_equals(animation.startTime, startTimeBeforePausing,
|
||||
'The startTime does not change when pausing-pending');
|
||||
return animation.ready;
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
assert_equals(animation.startTime, null,
|
||||
'After actually pausing, the startTime of an animation ' +
|
||||
'is null');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'Pausing should make the startTime become null');
|
||||
|
||||
test(function(t)
|
||||
@ -282,8 +277,7 @@ test(function(t)
|
||||
}, 'Sanity test to check round-tripping assigning to a new animation\'s ' +
|
||||
'startTime');
|
||||
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
|
||||
@ -291,12 +285,12 @@ async_test(function(t) {
|
||||
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
return animation.ready.then(function() {
|
||||
checkStateOnReadyPromiseResolved(animation);
|
||||
|
||||
animation.startTime = startTimeForStartOfActiveInterval(animation.timeline);
|
||||
return eventWatcher.wait_for('animationstart');
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
checkStateAtActiveIntervalStartTime(animation);
|
||||
|
||||
animation.startTime =
|
||||
@ -305,17 +299,12 @@ async_test(function(t) {
|
||||
|
||||
animation.startTime = startTimeForEndOfActiveInterval(animation.timeline);
|
||||
return eventWatcher.wait_for('animationend');
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
checkStateAtActiveIntervalEndTime(animation);
|
||||
})).catch(t.step_func(function(reason) {
|
||||
assert_unreached(reason);
|
||||
})).then(function() {
|
||||
t.done();
|
||||
});
|
||||
}, 'Skipping forward through animation');
|
||||
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
|
||||
@ -331,8 +320,8 @@ async_test(function(t) {
|
||||
// an 'animationend' event. We need to wait for these events before we start
|
||||
// testing going backwards since EventWatcher will fail the test if it gets
|
||||
// an event that we haven't told it about.
|
||||
eventWatcher.wait_for(['animationstart',
|
||||
'animationend']).then(t.step_func(function() {
|
||||
return eventWatcher.wait_for(['animationstart',
|
||||
'animationend']).then(function() {
|
||||
assert_true(document.timeline.currentTime - previousTimelineTime <
|
||||
ANIM_DUR_MS,
|
||||
'Sanity check that seeking worked rather than the events ' +
|
||||
@ -357,7 +346,7 @@ async_test(function(t) {
|
||||
var promise = eventWatcher.wait_for('animationstart');
|
||||
checkStateAtFiftyPctOfActiveInterval(animation);
|
||||
return promise;
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
animation.startTime = startTimeForStartOfActiveInterval(animation.timeline);
|
||||
checkStateAtActiveIntervalStartTime(animation);
|
||||
|
||||
@ -366,19 +355,13 @@ async_test(function(t) {
|
||||
// the animation start time, we now expect an animationend event
|
||||
// because we went from inside to outside the active interval.
|
||||
return eventWatcher.wait_for('animationend');
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
checkStateOnReadyPromiseResolved(animation);
|
||||
})).catch(t.step_func(function(reason) {
|
||||
assert_unreached(reason);
|
||||
})).then(function() {
|
||||
t.done();
|
||||
});
|
||||
})
|
||||
|
||||
// This must come after we've set up the Promise chain, since requesting
|
||||
// computed style will force events to be dispatched.
|
||||
// XXX For some reason this fails occasionally (either the animation.playState
|
||||
// check or the marginLeft check).
|
||||
//checkStateAtActiveIntervalEndTime(animation);
|
||||
checkStateAtActiveIntervalEndTime(animation);
|
||||
}, 'Skipping backwards through animation');
|
||||
|
||||
|
||||
@ -391,7 +374,7 @@ async_test(function(t) {
|
||||
// have happened, then assume that no events will ever be dispatched for the
|
||||
// redundant changes if no events were detected in that time.
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
@ -400,12 +383,10 @@ async_test(function(t) {
|
||||
animation.startTime = startTimeForActivePhase(animation.timeline);
|
||||
animation.startTime = startTimeForBeforePhase(animation.timeline);
|
||||
|
||||
waitForAnimationFrames(2).then(function() {
|
||||
t.done();
|
||||
});
|
||||
return waitForAnimationFrames(2);
|
||||
}, 'Redundant change, before -> active, then back');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
@ -414,87 +395,84 @@ async_test(function(t) {
|
||||
animation.startTime = startTimeForAfterPhase(animation.timeline);
|
||||
animation.startTime = startTimeForBeforePhase(animation.timeline);
|
||||
|
||||
waitForAnimationFrames(2).then(function() {
|
||||
t.done();
|
||||
});
|
||||
return waitForAnimationFrames(2);
|
||||
}, 'Redundant change, before -> after, then back');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
eventWatcher.wait_for('animationstart').then(function() {
|
||||
var retPromise = eventWatcher.wait_for('animationstart').then(function() {
|
||||
animation.startTime = startTimeForBeforePhase(animation.timeline);
|
||||
animation.startTime = startTimeForActivePhase(animation.timeline);
|
||||
|
||||
waitForAnimationFrames(2).then(function() {
|
||||
t.done();
|
||||
});
|
||||
return waitForAnimationFrames(2);
|
||||
});
|
||||
// get us into the initial state:
|
||||
animation.startTime = startTimeForActivePhase(animation.timeline);
|
||||
|
||||
return retPromise;
|
||||
}, 'Redundant change, active -> before, then back');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
eventWatcher.wait_for('animationstart').then(function() {
|
||||
var retPromise = eventWatcher.wait_for('animationstart').then(function() {
|
||||
animation.startTime = startTimeForAfterPhase(animation.timeline);
|
||||
animation.startTime = startTimeForActivePhase(animation.timeline);
|
||||
|
||||
waitForAnimationFrames(2).then(function() {
|
||||
t.done();
|
||||
});
|
||||
return waitForAnimationFrames(2);
|
||||
});
|
||||
// get us into the initial state:
|
||||
animation.startTime = startTimeForActivePhase(animation.timeline);
|
||||
|
||||
return retPromise;
|
||||
}, 'Redundant change, active -> after, then back');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
eventWatcher.wait_for(['animationstart',
|
||||
'animationend']).then(function() {
|
||||
var retPromise = eventWatcher.wait_for(['animationstart',
|
||||
'animationend']).then(function() {
|
||||
animation.startTime = startTimeForBeforePhase(animation.timeline);
|
||||
animation.startTime = startTimeForAfterPhase(animation.timeline);
|
||||
|
||||
waitForAnimationFrames(2).then(function() {
|
||||
t.done();
|
||||
});
|
||||
return waitForAnimationFrames(2);
|
||||
});
|
||||
// get us into the initial state:
|
||||
animation.startTime = startTimeForAfterPhase(animation.timeline);
|
||||
|
||||
return retPromise;
|
||||
}, 'Redundant change, after -> before, then back');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
var eventWatcher = new EventWatcher(t, div, CSS_ANIM_EVENTS);
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
eventWatcher.wait_for(['animationstart',
|
||||
'animationend']).then(function() {
|
||||
var retPromise = eventWatcher.wait_for(['animationstart',
|
||||
'animationend']).then(function() {
|
||||
animation.startTime = startTimeForActivePhase(animation.timeline);
|
||||
animation.startTime = startTimeForAfterPhase(animation.timeline);
|
||||
|
||||
waitForAnimationFrames(2).then(function() {
|
||||
t.done();
|
||||
});
|
||||
return waitForAnimationFrames(2);
|
||||
});
|
||||
// get us into the initial state:
|
||||
animation.startTime = startTimeForAfterPhase(animation.timeline);
|
||||
|
||||
return retPromise;
|
||||
}, 'Redundant change, after -> active, then back');
|
||||
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
div.style.animation = ANIM_PROPERTY_VAL;
|
||||
|
||||
@ -502,27 +480,23 @@ async_test(function(t) {
|
||||
|
||||
var storedCurrentTime;
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
return animation.ready.then(function() {
|
||||
storedCurrentTime = animation.currentTime;
|
||||
animation.startTime = null;
|
||||
return animation.ready;
|
||||
})).catch(t.step_func(function(reason) {
|
||||
assert_unreached(reason);
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
assert_equals(animation.currentTime, storedCurrentTime,
|
||||
'Test that hold time is correct');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'Setting startTime to null');
|
||||
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
div.style.animation = 'anim 100s';
|
||||
|
||||
var animation = div.getAnimations()[0];
|
||||
|
||||
animation.ready.then(t.step_func(function() {
|
||||
return animation.ready.then(function() {
|
||||
var savedStartTime = animation.startTime;
|
||||
|
||||
assert_not_equals(animation.startTime, null,
|
||||
@ -530,29 +504,24 @@ async_test(function(t) {
|
||||
|
||||
animation.pause();
|
||||
return animation.ready;
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
assert_equals(animation.startTime, null,
|
||||
'Animation.startTime is null after paused');
|
||||
assert_equals(animation.playState, 'paused',
|
||||
'Animation.playState is "paused" after pause() call');
|
||||
})).catch(t.step_func(function(reason) {
|
||||
assert_unreached(reason);
|
||||
})).then(function() {
|
||||
t.done();
|
||||
});
|
||||
}, 'Animation.startTime after pausing');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t, {'class': 'animated-div'});
|
||||
div.style.animation = 'anim 100s';
|
||||
|
||||
var animation = div.getAnimations()[0];
|
||||
animation.ready.then(t.step_func(function() {
|
||||
return animation.ready.then(function() {
|
||||
animation.cancel();
|
||||
assert_equals(animation.startTime, null,
|
||||
'The startTime of a cancelled animation should be null');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'Animation.startTime after cancelling');
|
||||
|
||||
done();
|
||||
|
@ -11,24 +11,23 @@
|
||||
<script>
|
||||
'use strict';
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = 'anim1 100s';
|
||||
|
||||
var originalAnimation = div.getAnimations()[0];
|
||||
var originalStartTime;
|
||||
var originalCurrentTime;
|
||||
|
||||
// Wait a moment so we can confirm the startTime doesn't change (and doesn't
|
||||
// simply reflect the current time).
|
||||
originalAnimation.ready.then(function() {
|
||||
return originalAnimation.ready.then(function() {
|
||||
originalStartTime = originalAnimation.startTime;
|
||||
originalCurrentTime = originalAnimation.currentTime;
|
||||
|
||||
// Wait a moment so we can confirm the startTime doesn't change (and
|
||||
// doesn't simply reflect the current time).
|
||||
return waitForFrame();
|
||||
}).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
div.style.animationDuration = '200s';
|
||||
var animation = div.getAnimations()[0];
|
||||
assert_equals(animation, originalAnimation,
|
||||
@ -41,8 +40,7 @@ async_test(function(t) {
|
||||
assert_not_equals(animation.currentTime, originalCurrentTime,
|
||||
'Animation.currentTime has updated in next'
|
||||
+ ' requestAnimationFrame callback');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'Animations preserve their startTime when changed');
|
||||
|
||||
test(function(t) {
|
||||
@ -63,7 +61,7 @@ test(function(t) {
|
||||
'Second Animation is in same position after update');
|
||||
}, 'Updated Animations maintain their order in the list');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = 'anim1 200s, anim1 100s';
|
||||
|
||||
@ -75,7 +73,7 @@ async_test(function(t) {
|
||||
// Wait before continuing so we can compare start times (otherwise the
|
||||
// new Animation objects and existing Animation objects will all have the same
|
||||
// start time).
|
||||
waitForAllAnimations(animations).then(waitForFrame).then(t.step_func(function() {
|
||||
return waitForAllAnimations(animations).then(waitForFrame).then(function() {
|
||||
// Swap duration of first and second in list and prepend animation at the
|
||||
// same time
|
||||
div.style.animation = 'anim1 100s, anim1 100s, anim1 200s';
|
||||
@ -90,20 +88,19 @@ async_test(function(t) {
|
||||
'Old Animations have the same start time');
|
||||
// TODO: Check that animations[0].startTime === null
|
||||
return animations[0].ready;
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
assert_true(animations[0].startTime > animations[1].startTime,
|
||||
'New Animation has later start time');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'Only the startTimes of existing animations are preserved');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = 'anim1 100s, anim1 100s';
|
||||
var secondAnimation = div.getAnimations()[1];
|
||||
|
||||
// Wait before continuing so we can compare start times
|
||||
secondAnimation.ready.then(waitForFrame).then(t.step_func(function() {
|
||||
return secondAnimation.ready.then(waitForFrame).then(function() {
|
||||
// Trim list of animations
|
||||
div.style.animationName = 'anim1';
|
||||
var animations = div.getAnimations();
|
||||
@ -114,12 +111,11 @@ async_test(function(t) {
|
||||
'Remaining Animation has resolved startTime');
|
||||
assert_true(animations[0].startTime < animations[0].timeline.currentTime,
|
||||
'Remaining Animation preserves startTime');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'Animations are removed from the start of the list while preserving'
|
||||
+ ' the state of existing Animations');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = 'anim1 100s';
|
||||
var firstAddedAnimation = div.getAnimations()[0],
|
||||
@ -127,13 +123,13 @@ async_test(function(t) {
|
||||
animations;
|
||||
|
||||
// Wait and add second Animation
|
||||
firstAddedAnimation.ready.then(waitForFrame).then(t.step_func(function() {
|
||||
return firstAddedAnimation.ready.then(waitForFrame).then(function() {
|
||||
div.style.animation = 'anim1 100s, anim1 100s';
|
||||
secondAddedAnimation = div.getAnimations()[0];
|
||||
|
||||
// Wait again and add another Animation
|
||||
return secondAddedAnimation.ready.then(waitForFrame);
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
div.style.animation = 'anim1 100s, anim2 100s, anim1 100s';
|
||||
animations = div.getAnimations();
|
||||
assert_not_equals(firstAddedAnimation, secondAddedAnimation,
|
||||
@ -145,13 +141,12 @@ async_test(function(t) {
|
||||
'First Animation remains in same position after'
|
||||
+ ' interleaving');
|
||||
return animations[1].ready;
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
assert_true(animations[1].startTime > animations[0].startTime,
|
||||
'Interleaved animation starts later than existing animations');
|
||||
assert_true(animations[0].startTime > animations[2].startTime,
|
||||
'Original animations retain their start time');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'Animation state is preserved when interleaving animations in list');
|
||||
|
||||
done();
|
||||
|
@ -32,7 +32,7 @@ test(function(t) {
|
||||
var pseudoTarget = document.getAnimations()[0].effect.target;
|
||||
var effect = new KeyframeEffectReadOnly(pseudoTarget,
|
||||
{ background: ["blue", "red"] },
|
||||
3000);
|
||||
3 * MS_PER_SEC);
|
||||
var newAnim = new Animation(effect, document.timeline);
|
||||
newAnim.play();
|
||||
var anims = document.getAnimations();
|
||||
|
@ -24,7 +24,7 @@ test(function(t) {
|
||||
+ ' with no animations');
|
||||
}, 'getAnimations for non-animated content');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
|
||||
// FIXME: This test does too many things. It should be split up.
|
||||
@ -34,7 +34,7 @@ async_test(function(t) {
|
||||
var animations = div.getAnimations();
|
||||
assert_equals(animations.length, 1,
|
||||
'getAnimations returns an Animation running CSS Animations');
|
||||
animations[0].ready.then(t.step_func(function() {
|
||||
return animations[0].ready.then(function() {
|
||||
var startTime = animations[0].startTime;
|
||||
assert_true(startTime > 0 && startTime <= document.timeline.currentTime,
|
||||
'CSS animation has a sensible start time');
|
||||
@ -44,7 +44,7 @@ async_test(function(t) {
|
||||
// We wait for the next frame so that we can test that the start times of
|
||||
// the animations differ.
|
||||
return waitForFrame();
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
div.style.animation = 'anim1 100s, anim2 100s';
|
||||
animations = div.getAnimations();
|
||||
assert_equals(animations.length, 2,
|
||||
@ -54,12 +54,11 @@ async_test(function(t) {
|
||||
// (We don't make any assumptions about the order of the Animations since
|
||||
// that is the purpose of the following test.)
|
||||
return waitForAllAnimations(animations);
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
assert_true(animations[0].startTime < animations[1].startTime,
|
||||
'Additional Animations for CSS animations start after the original'
|
||||
+ ' animation and appear later in the list');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'getAnimations for CSS Animations');
|
||||
|
||||
test(function(t) {
|
||||
@ -78,7 +77,7 @@ test(function(t) {
|
||||
+ ' that targets multiple properties');
|
||||
}, 'getAnimations for multi-property animations');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
|
||||
// Add an animation
|
||||
@ -88,7 +87,7 @@ async_test(function(t) {
|
||||
|
||||
// Wait until a frame after the animation starts, then add a transition
|
||||
var animations = div.getAnimations();
|
||||
animations[0].ready.then(waitForFrame).then(t.step_func(function() {
|
||||
return animations[0].ready.then(waitForFrame).then(function() {
|
||||
div.style.transition = 'all 100s';
|
||||
div.style.backgroundColor = 'green';
|
||||
|
||||
@ -100,8 +99,7 @@ async_test(function(t) {
|
||||
'First-returned animation is the CSS Transition');
|
||||
assert_class_string(animations[1], 'CSSAnimation',
|
||||
'Second-returned animation is the CSS Animation');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'getAnimations for both CSS Animations and CSS Transitions at once');
|
||||
|
||||
async_test(function(t) {
|
||||
@ -166,7 +164,7 @@ test(function(t) {
|
||||
+ ' animation-name is found');
|
||||
}, 'getAnimations for CSS Animations with animation-name: missing');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = 'anim1 100s, notyet 100s';
|
||||
var animations = div.getAnimations();
|
||||
@ -174,7 +172,7 @@ async_test(function(t) {
|
||||
'getAnimations initally only returns Animations for CSS Animations whose'
|
||||
+ ' animation-name is found');
|
||||
|
||||
animations[0].ready.then(waitForFrame).then(t.step_func(function() {
|
||||
return animations[0].ready.then(waitForFrame).then(function() {
|
||||
var keyframes = '@keyframes notyet { to { left: 100px; } }';
|
||||
document.styleSheets[0].insertRule(keyframes, 0);
|
||||
animations = div.getAnimations();
|
||||
@ -182,12 +180,11 @@ async_test(function(t) {
|
||||
'getAnimations includes Animation when @keyframes rule is added'
|
||||
+ ' later');
|
||||
return waitForAllAnimations(animations);
|
||||
})).then(t.step_func(function() {
|
||||
}).then(function() {
|
||||
assert_true(animations[0].startTime < animations[1].startTime,
|
||||
'Newly added animation has a later start time');
|
||||
document.styleSheets[0].deleteRule(0);
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'getAnimations for CSS Animations where the @keyframes rule is added'
|
||||
+ ' later');
|
||||
|
||||
@ -207,19 +204,18 @@ test(function(t) {
|
||||
+ ' empty keyframes rule');
|
||||
}, 'getAnimations for CSS Animations with empty keyframes rule');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = 'anim1 100s 100s';
|
||||
var animations = div.getAnimations();
|
||||
assert_equals(animations.length, 1,
|
||||
'getAnimations returns animations for CSS animations whose'
|
||||
+ ' delay makes them start later');
|
||||
animations[0].ready.then(waitForFrame).then(t.step_func(function() {
|
||||
return animations[0].ready.then(waitForFrame).then(function() {
|
||||
assert_true(animations[0].startTime <= document.timeline.currentTime,
|
||||
'For CSS Animations in delay phase, the start time of the Animation is'
|
||||
+ ' not in the future');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'getAnimations for CSS animations in delay phase');
|
||||
|
||||
test(function(t) {
|
||||
@ -274,11 +270,11 @@ test(function(t) {
|
||||
|
||||
}, 'getAnimations for CSS Animations that are cancelled');
|
||||
|
||||
async_test(function(t) {
|
||||
promise_test(function(t) {
|
||||
var div = addDiv(t);
|
||||
div.style.animation = 'anim2 100s';
|
||||
|
||||
div.getAnimations()[0].ready.then(t.step_func(function() {
|
||||
return div.getAnimations()[0].ready.then(function() {
|
||||
// Prepend to the list and test that even though anim1 was triggered
|
||||
// *after* anim2, it should come first because it appears first
|
||||
// in the animation-name property.
|
||||
@ -300,8 +296,7 @@ async_test(function(t) {
|
||||
'animation order after cancelling and restarting');
|
||||
assert_equals(anims[1].animationName, 'anim2',
|
||||
'animation order after cancelling and restarting');
|
||||
t.done();
|
||||
}));
|
||||
});
|
||||
}, 'getAnimations for CSS Animations follows animation-name order');
|
||||
|
||||
test(function(t) {
|
||||
|
@ -42,7 +42,7 @@ test(function(t) {
|
||||
var pseudoTarget = document.getAnimations()[0].effect.target;
|
||||
var effect = new KeyframeEffectReadOnly(pseudoTarget,
|
||||
{ background: ["blue", "red"] },
|
||||
3000);
|
||||
3 * MS_PER_SEC);
|
||||
var newAnimation = new Animation(effect, document.timeline);
|
||||
newAnimation.id = 'scripted-anim';
|
||||
newAnimation.play();
|
||||
|
@ -1,15 +0,0 @@
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
setup({explicit_done: true});
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ "set": [["dom.animations-api.core.enabled", true]]},
|
||||
function() {
|
||||
window.open("file_animation-oncancel.html");
|
||||
});
|
||||
</script>
|
||||
</html>
|
@ -1,15 +0,0 @@
|
||||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
'use strict';
|
||||
setup({explicit_done: true});
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{ "set": [["dom.animations-api.core.enabled", true]]},
|
||||
function() {
|
||||
window.open("file_animation-onfinish.html");
|
||||
});
|
||||
</script>
|
||||
</html>
|
@ -9,8 +9,6 @@ support-files =
|
||||
css-animations/file_animation-finish.html
|
||||
css-animations/file_animation-finished.html
|
||||
css-animations/file_animation-id.html
|
||||
css-animations/file_animation-oncancel.html
|
||||
css-animations/file_animation-onfinish.html
|
||||
css-animations/file_animation-pausing.html
|
||||
css-animations/file_animation-playstate.html
|
||||
css-animations/file_animation-ready.html
|
||||
@ -49,8 +47,6 @@ support-files =
|
||||
[css-animations/test_animation-finish.html]
|
||||
[css-animations/test_animation-finished.html]
|
||||
[css-animations/test_animation-id.html]
|
||||
[css-animations/test_animation-oncancel.html]
|
||||
[css-animations/test_animation-onfinish.html]
|
||||
[css-animations/test_animation-pausing.html]
|
||||
[css-animations/test_animation-playstate.html]
|
||||
[css-animations/test_animation-ready.html]
|
||||
|
@ -57,7 +57,7 @@
|
||||
#define CONSOLE_TAG_BLOB JS_SCTAG_USER_MIN
|
||||
|
||||
// This value is taken from ConsoleAPIStorage.js
|
||||
#define STORAGE_MAX_EVENTS 200
|
||||
#define STORAGE_MAX_EVENTS 1000
|
||||
|
||||
using namespace mozilla::dom::exceptions;
|
||||
using namespace mozilla::dom::workers;
|
||||
|
@ -14,7 +14,7 @@ Cu.import("resource://gre/modules/Services.jsm");
|
||||
// This constant tells how many messages to process in a single timer execution.
|
||||
const MESSAGES_IN_INTERVAL = 1500
|
||||
|
||||
const STORAGE_MAX_EVENTS = 200;
|
||||
const STORAGE_MAX_EVENTS = 1000;
|
||||
|
||||
var _consoleStorage = new Map();
|
||||
|
||||
|
@ -75,6 +75,18 @@ public:
|
||||
|
||||
void GetName(nsString& retval);
|
||||
|
||||
virtual void GetErrorMessage(nsAString& aRetVal)
|
||||
{
|
||||
// Since GetName and GetMessageMoz are non-virtual and they deal with
|
||||
// different member variables in Exception vs. DOMException, have a
|
||||
// virtual method to ensure the right error message creation.
|
||||
nsAutoString name;
|
||||
nsAutoString message;
|
||||
GetName(name);
|
||||
GetMessageMoz(message);
|
||||
CreateErrorMessage(name, message, aRetVal);
|
||||
}
|
||||
|
||||
// The XPCOM GetFilename does the right thing. It might throw, but we want to
|
||||
// return an empty filename in that case anyway, instead of throwing.
|
||||
|
||||
@ -102,6 +114,23 @@ public:
|
||||
protected:
|
||||
virtual ~Exception();
|
||||
|
||||
void CreateErrorMessage(const nsAString& aName, const nsAString& aMessage,
|
||||
nsAString& aRetVal)
|
||||
{
|
||||
// Create similar error message as what ErrorReport::init does in jsexn.cpp.
|
||||
if (!aName.IsEmpty() && !aMessage.IsEmpty()) {
|
||||
aRetVal.Assign(aName);
|
||||
aRetVal.AppendLiteral(": ");
|
||||
aRetVal.Append(aMessage);
|
||||
} else if (!aName.IsEmpty()) {
|
||||
aRetVal.Assign(aName);
|
||||
} else if (!aMessage.IsEmpty()) {
|
||||
aRetVal.Assign(aMessage);
|
||||
} else {
|
||||
aRetVal.Truncate();
|
||||
}
|
||||
}
|
||||
|
||||
nsCString mMessage;
|
||||
nsresult mResult;
|
||||
nsCString mName;
|
||||
@ -151,6 +180,16 @@ public:
|
||||
void GetMessageMoz(nsString& retval);
|
||||
void GetName(nsString& retval);
|
||||
|
||||
virtual void GetErrorMessage(nsAString& aRetVal) override
|
||||
{
|
||||
// See the comment in Exception::GetErrorMessage.
|
||||
nsAutoString name;
|
||||
nsAutoString message;
|
||||
GetName(name);
|
||||
GetMessageMoz(message);
|
||||
CreateErrorMessage(name, message, aRetVal);
|
||||
}
|
||||
|
||||
static already_AddRefed<DOMException>
|
||||
Create(nsresult aRv);
|
||||
|
||||
|
@ -2083,7 +2083,7 @@ Element::DispatchClickEvent(nsPresContext* aPresContext,
|
||||
|
||||
WidgetMouseEvent event(aSourceEvent->IsTrusted(), eMouseClick,
|
||||
aSourceEvent->mWidget, WidgetMouseEvent::eReal);
|
||||
event.refPoint = aSourceEvent->refPoint;
|
||||
event.mRefPoint = aSourceEvent->mRefPoint;
|
||||
uint32_t clickCount = 1;
|
||||
float pressure = 0;
|
||||
uint16_t inputSource = 0;
|
||||
@ -3025,7 +3025,7 @@ Element::PostHandleEventForLinks(EventChainPostVisitor& aVisitor)
|
||||
}
|
||||
case eLegacyDOMActivate:
|
||||
{
|
||||
if (aVisitor.mEvent->originalTarget == this) {
|
||||
if (aVisitor.mEvent->mOriginalTarget == this) {
|
||||
nsAutoString target;
|
||||
GetLinkTarget(target);
|
||||
const InternalUIEvent* activeEvent = aVisitor.mEvent->AsUIEvent();
|
||||
|
@ -692,7 +692,7 @@ nsIContent::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
||||
// dispatched or when we're about to propagate from
|
||||
// chrome access only subtree or if we are about to propagate out of
|
||||
// a shadow root to a shadow root host.
|
||||
((this == aVisitor.mEvent->originalTarget &&
|
||||
((this == aVisitor.mEvent->mOriginalTarget &&
|
||||
!ChromeOnlyAccess()) || isAnonForEvents || GetShadowRoot())) {
|
||||
nsCOMPtr<nsIContent> relatedTarget =
|
||||
do_QueryInterface(aVisitor.mEvent->AsMouseEvent()->relatedTarget);
|
||||
@ -717,7 +717,7 @@ nsIContent::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
||||
// If this is the original target, aVisitor.mRelatedTargetIsInAnon
|
||||
// must be updated.
|
||||
if (isAnonForEvents || aVisitor.mRelatedTargetIsInAnon ||
|
||||
(aVisitor.mEvent->originalTarget == this &&
|
||||
(aVisitor.mEvent->mOriginalTarget == this &&
|
||||
(aVisitor.mRelatedTargetIsInAnon =
|
||||
relatedTarget->ChromeOnlyAccess()))) {
|
||||
nsIContent* anonOwner = FindChromeAccessOnlySubtreeOwner(this);
|
||||
@ -736,7 +736,7 @@ nsIContent::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
||||
if (anonOwner == anonOwnerRelated) {
|
||||
#ifdef DEBUG_smaug
|
||||
nsCOMPtr<nsIContent> originalTarget =
|
||||
do_QueryInterface(aVisitor.mEvent->originalTarget);
|
||||
do_QueryInterface(aVisitor.mEvent->mOriginalTarget);
|
||||
nsAutoString ot, ct, rt;
|
||||
if (originalTarget) {
|
||||
originalTarget->NodeInfo()->NameAtom()->ToString(ot);
|
||||
@ -875,7 +875,8 @@ nsIContent::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
||||
#ifdef DEBUG
|
||||
// If a DOM event is explicitly dispatched using node.dispatchEvent(), then
|
||||
// all the events are allowed even in the native anonymous content..
|
||||
nsCOMPtr<nsIContent> t = do_QueryInterface(aVisitor.mEvent->originalTarget);
|
||||
nsCOMPtr<nsIContent> t =
|
||||
do_QueryInterface(aVisitor.mEvent->mOriginalTarget);
|
||||
NS_ASSERTION(!t || !t->ChromeOnlyAccess() ||
|
||||
aVisitor.mEvent->mClass != eMutationEventClass ||
|
||||
aVisitor.mDOMEvent,
|
||||
@ -883,7 +884,7 @@ nsIContent::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
||||
#endif
|
||||
aVisitor.mEventTargetAtParent = parent;
|
||||
} else if (parent && aVisitor.mOriginalTargetIsInAnon) {
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->target));
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->mTarget));
|
||||
if (content && content->GetBindingParent() == parent) {
|
||||
aVisitor.mEventTargetAtParent = parent;
|
||||
}
|
||||
|
@ -429,7 +429,6 @@ ResponsiveImageSelector::ComputeFinalWidthForCurrentViewport(double *aWidth)
|
||||
nsPresContext *pctx = presShell ? presShell->GetPresContext() : nullptr;
|
||||
|
||||
if (!pctx) {
|
||||
MOZ_ASSERT(false, "Unable to find presContext for this content");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -574,7 +574,8 @@ AutoJSAPI::ReportException()
|
||||
JSAutoCompartment ac(cx(), errorGlobal);
|
||||
JS::Rooted<JS::Value> exn(cx());
|
||||
js::ErrorReport jsReport(cx());
|
||||
if (StealException(&exn) && jsReport.init(cx(), exn)) {
|
||||
if (StealException(&exn) &&
|
||||
jsReport.init(cx(), exn, js::ErrorReport::WithSideEffects)) {
|
||||
if (mIsMainThread) {
|
||||
RefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
|
||||
|
||||
|
@ -254,8 +254,9 @@ TextInputProcessor::IsValidEventTypeForComposition(
|
||||
return true;
|
||||
}
|
||||
if (aKeyboardEvent.mMessage == eUnidentifiedEvent &&
|
||||
aKeyboardEvent.userType &&
|
||||
nsDependentAtomString(aKeyboardEvent.userType).EqualsLiteral("on")) {
|
||||
aKeyboardEvent.mSpecifiedEventType &&
|
||||
nsDependentAtomString(
|
||||
aKeyboardEvent.mSpecifiedEventType).EqualsLiteral("on")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
22
dom/base/crashtests/1158412.html
Normal file
22
dom/base/crashtests/1158412.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
document.styleSheetSets.expando = null;
|
||||
var otherDoc = document.implementation.createDocument("", "", null);
|
||||
var otherSpan = otherDoc.createElementNS("http://www.w3.org/1999/xhtml", "span");
|
||||
|
||||
var img = document.createElementNS("http://www.w3.org/1999/xhtml", "img");
|
||||
img.srcset = "data:,a 1w, data:,b 1w";
|
||||
img.sizes = "1px";
|
||||
otherSpan.appendChild(img);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="boom();"></body>
|
||||
</html>
|
@ -199,6 +199,7 @@ pref(dom.webcomponents.enabled,true) load 1027461-1.html
|
||||
pref(dom.webcomponents.enabled,true) load 1029710.html
|
||||
load 1154598.xhtml
|
||||
load 1157995.html
|
||||
load 1158412.html
|
||||
load 1181619.html
|
||||
load structured_clone_container_throws.html
|
||||
HTTP(..) load xhr_abortinprogress.html
|
||||
|
@ -5285,7 +5285,7 @@ nsContentUtils::SetDataTransferInEvent(WidgetDragEvent* aDragEvent)
|
||||
// from another application. In either case, a new dataTransfer should
|
||||
// be created that reflects the data.
|
||||
initialDataTransfer =
|
||||
new DataTransfer(aDragEvent->target, aDragEvent->mMessage, true, -1);
|
||||
new DataTransfer(aDragEvent->mTarget, aDragEvent->mMessage, true, -1);
|
||||
|
||||
// now set it in the drag session so we don't need to create it again
|
||||
dragSession->SetDataTransfer(initialDataTransfer);
|
||||
@ -5298,7 +5298,7 @@ nsContentUtils::SetDataTransferInEvent(WidgetDragEvent* aDragEvent)
|
||||
}
|
||||
|
||||
// each event should use a clone of the original dataTransfer.
|
||||
initialDataTransfer->Clone(aDragEvent->target, aDragEvent->mMessage,
|
||||
initialDataTransfer->Clone(aDragEvent->mTarget, aDragEvent->mMessage,
|
||||
aDragEvent->mUserCancelled,
|
||||
isCrossDomainSubFrameDrop,
|
||||
getter_AddRefs(aDragEvent->mDataTransfer));
|
||||
@ -5369,7 +5369,7 @@ bool
|
||||
nsContentUtils::CheckForSubFrameDrop(nsIDragSession* aDragSession,
|
||||
WidgetDragEvent* aDropEvent)
|
||||
{
|
||||
nsCOMPtr<nsIContent> target = do_QueryInterface(aDropEvent->originalTarget);
|
||||
nsCOMPtr<nsIContent> target = do_QueryInterface(aDropEvent->mOriginalTarget);
|
||||
if (!target) {
|
||||
return true;
|
||||
}
|
||||
@ -7726,7 +7726,7 @@ nsContentUtils::SendKeyEvent(nsIWidget* aWidget,
|
||||
break;
|
||||
}
|
||||
|
||||
event.refPoint.x = event.refPoint.y = 0;
|
||||
event.mRefPoint = LayoutDeviceIntPoint(0, 0);
|
||||
event.mTime = PR_IntervalNow();
|
||||
if (!(aAdditionalFlags & nsIDOMWindowUtils::KEY_FLAG_NOT_SYNTHESIZED_FOR_TESTS)) {
|
||||
event.mFlags.mIsSynthesizedForTests = true;
|
||||
@ -7808,7 +7808,7 @@ nsContentUtils::SendMouseEvent(nsCOMPtr<nsIPresShell> aPresShell,
|
||||
if (!presContext)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
|
||||
event.mRefPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
|
||||
event.ignoreRootScrollFrame = aIgnoreRootScrollFrame;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
|
@ -689,7 +689,8 @@ nsDOMWindowUtils::SendPointerEventCommon(const nsAString& aType,
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
event.refPoint = nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
|
||||
event.mRefPoint =
|
||||
nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
|
||||
event.ignoreRootScrollFrame = aIgnoreRootScrollFrame;
|
||||
|
||||
nsEventStatus status;
|
||||
@ -810,7 +811,8 @@ nsDOMWindowUtils::SendWheelEvent(float aX,
|
||||
nsPresContext* presContext = GetPresContext();
|
||||
NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
|
||||
|
||||
wheelEvent.refPoint = nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
|
||||
wheelEvent.mRefPoint =
|
||||
nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
|
||||
|
||||
widget->DispatchInputEvent(&wheelEvent);
|
||||
|
||||
@ -1299,7 +1301,8 @@ nsDOMWindowUtils::SendSimpleGestureEvent(const nsAString& aType,
|
||||
if (!presContext)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
event.refPoint = nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
|
||||
event.mRefPoint =
|
||||
nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
|
||||
|
||||
nsEventStatus status;
|
||||
return widget->DispatchEvent(&event, status);
|
||||
@ -1797,7 +1800,7 @@ static void
|
||||
InitEvent(WidgetGUIEvent& aEvent, LayoutDeviceIntPoint* aPt = nullptr)
|
||||
{
|
||||
if (aPt) {
|
||||
aEvent.refPoint = *aPt;
|
||||
aEvent.mRefPoint = *aPt;
|
||||
}
|
||||
aEvent.mTime = PR_IntervalNow();
|
||||
}
|
||||
@ -2258,15 +2261,6 @@ ComputeAnimationValue(nsCSSProperty aProperty,
|
||||
aInput, false, aOutput)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// This matches TransExtractComputedValue in nsTransitionManager.cpp.
|
||||
if (aProperty == eCSSProperty_visibility) {
|
||||
MOZ_ASSERT(aOutput.GetUnit() == StyleAnimationValue::eUnit_Enumerated,
|
||||
"unexpected unit");
|
||||
aOutput.SetIntValue(aOutput.GetIntValue(),
|
||||
StyleAnimationValue::eUnit_Visibility);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -274,6 +274,7 @@ GK_ATOM(decimalFormat, "decimal-format")
|
||||
GK_ATOM(decimalSeparator, "decimal-separator")
|
||||
GK_ATOM(deck, "deck")
|
||||
GK_ATOM(declare, "declare")
|
||||
GK_ATOM(decoderDoctor, "decoder-doctor")
|
||||
GK_ATOM(decrement, "decrement")
|
||||
GK_ATOM(_default, "default")
|
||||
GK_ATOM(headerDefaultStyle, "default-style")
|
||||
|
@ -3113,8 +3113,8 @@ nsGlobalWindow::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
||||
//let's only take the lowest half of the point structure.
|
||||
int16_t myCoord[2];
|
||||
|
||||
myCoord[0] = aVisitor.mEvent->refPoint.x;
|
||||
myCoord[1] = aVisitor.mEvent->refPoint.y;
|
||||
myCoord[0] = aVisitor.mEvent->mRefPoint.x;
|
||||
myCoord[1] = aVisitor.mEvent->mRefPoint.y;
|
||||
gEntropyCollector->RandomUpdate((void*)myCoord, sizeof(myCoord));
|
||||
gEntropyCollector->RandomUpdate((void*)&(aVisitor.mEvent->mTime),
|
||||
sizeof(uint32_t));
|
||||
@ -3123,7 +3123,7 @@ nsGlobalWindow::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
||||
// QIing to window so that we can keep the old behavior also in case
|
||||
// a child window is handling resize.
|
||||
nsCOMPtr<nsPIDOMWindowInner> window =
|
||||
do_QueryInterface(aVisitor.mEvent->originalTarget);
|
||||
do_QueryInterface(aVisitor.mEvent->mOriginalTarget);
|
||||
if (window) {
|
||||
mIsHandlingResizeEvent = true;
|
||||
}
|
||||
|
@ -922,6 +922,10 @@ nsLocation::Replace(const nsAString& aUrl)
|
||||
NS_IMETHODIMP
|
||||
nsLocation::Assign(const nsAString& aUrl)
|
||||
{
|
||||
if (JSContext *cx = nsContentUtils::GetCurrentJSContext()) {
|
||||
return SetHrefWithContext(cx, aUrl, false);
|
||||
}
|
||||
|
||||
nsAutoString oldHref;
|
||||
nsresult result = NS_OK;
|
||||
|
||||
|
@ -29,7 +29,7 @@ FakeMediaStreamGraph::DispatchToMainThreadAfterStreamStateUpdate(already_AddRefe
|
||||
}
|
||||
|
||||
CameraPreviewMediaStream::CameraPreviewMediaStream(DOMMediaStream* aWrapper)
|
||||
: MediaStream(aWrapper)
|
||||
: ProcessedMediaStream(aWrapper)
|
||||
, mMutex("mozilla::camera::CameraPreviewMediaStream")
|
||||
, mInvalidatePending(0)
|
||||
, mDiscardedFrames(0)
|
||||
@ -130,6 +130,13 @@ CameraPreviewMediaStream::Invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::ProcessInput(GraphTime aFrom, GraphTime aTo,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
CameraPreviewMediaStream::RateLimit(bool aLimit)
|
||||
{
|
||||
|
@ -35,7 +35,7 @@ protected:
|
||||
* A camera preview requests no delay and no buffering stream,
|
||||
* but the SourceMediaStream does not support it.
|
||||
*/
|
||||
class CameraPreviewMediaStream : public MediaStream
|
||||
class CameraPreviewMediaStream : public ProcessedMediaStream
|
||||
{
|
||||
typedef mozilla::layers::Image Image;
|
||||
|
||||
@ -56,6 +56,8 @@ public:
|
||||
|
||||
void Invalidate();
|
||||
|
||||
void ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags) override;
|
||||
|
||||
// Call these on any thread.
|
||||
void SetCurrentFrame(const gfx::IntSize& aIntrinsicSize, Image* aImage);
|
||||
void ClearCurrentFrame();
|
||||
|
@ -262,6 +262,7 @@ nsDOMCameraControl::nsDOMCameraControl(uint32_t aCameraId,
|
||||
{
|
||||
DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
|
||||
mInput = new CameraPreviewMediaStream(this);
|
||||
mOwnedStream = mInput;
|
||||
|
||||
BindToOwner(aWindow);
|
||||
|
||||
|
@ -3773,7 +3773,7 @@ struct MOZ_STACK_CLASS CanvasBidiProcessor : public nsBidiPresUtils::BidiProcess
|
||||
}
|
||||
|
||||
// current text run
|
||||
nsAutoPtr<gfxTextRun> mTextRun;
|
||||
UniquePtr<gfxTextRun> mTextRun;
|
||||
|
||||
// pointer to a screen reference context used to measure text and such
|
||||
RefPtr<DrawTarget> mDrawTarget;
|
||||
|
@ -1547,9 +1547,9 @@ ContentEventHandler::OnQueryCharacterAtPoint(WidgetQueryContentEvent* aEvent)
|
||||
WidgetQueryContentEvent eventOnRoot(true, eQueryCharacterAtPoint,
|
||||
rootWidget);
|
||||
eventOnRoot.mUseNativeLineBreak = aEvent->mUseNativeLineBreak;
|
||||
eventOnRoot.refPoint = aEvent->refPoint;
|
||||
eventOnRoot.mRefPoint = aEvent->mRefPoint;
|
||||
if (rootWidget != aEvent->mWidget) {
|
||||
eventOnRoot.refPoint += aEvent->mWidget->WidgetToScreenOffset() -
|
||||
eventOnRoot.mRefPoint += aEvent->mWidget->WidgetToScreenOffset() -
|
||||
rootWidget->WidgetToScreenOffset();
|
||||
}
|
||||
nsPoint ptInRoot =
|
||||
@ -1645,7 +1645,7 @@ ContentEventHandler::OnQueryDOMWidgetHittest(WidgetQueryContentEvent* aEvent)
|
||||
NS_ENSURE_TRUE(docFrame, NS_ERROR_FAILURE);
|
||||
|
||||
LayoutDeviceIntPoint eventLoc =
|
||||
aEvent->refPoint + aEvent->mWidget->WidgetToScreenOffset();
|
||||
aEvent->mRefPoint + aEvent->mWidget->WidgetToScreenOffset();
|
||||
nsIntRect docFrameRect = docFrame->GetScreenRect(); // Returns CSS pixels
|
||||
CSSIntPoint eventLocCSS(
|
||||
mPresContext->DevPixelsToIntCSSPixels(eventLoc.x) - docFrameRect.x,
|
||||
|
@ -25,7 +25,7 @@ DragEvent::DragEvent(EventTarget* aOwner,
|
||||
else {
|
||||
mEventIsInternal = true;
|
||||
mEvent->mTime = PR_Now();
|
||||
mEvent->refPoint.x = mEvent->refPoint.y = 0;
|
||||
mEvent->mRefPoint = LayoutDeviceIntPoint(0, 0);
|
||||
mEvent->AsMouseEvent()->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
@ -153,9 +153,9 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Event)
|
||||
if (tmp->mEventIsInternal) {
|
||||
tmp->mEvent->target = nullptr;
|
||||
tmp->mEvent->currentTarget = nullptr;
|
||||
tmp->mEvent->originalTarget = nullptr;
|
||||
tmp->mEvent->mTarget = nullptr;
|
||||
tmp->mEvent->mCurrentTarget = nullptr;
|
||||
tmp->mEvent->mOriginalTarget = nullptr;
|
||||
switch (tmp->mEvent->mClass) {
|
||||
case eMouseEventClass:
|
||||
case eMouseScrollEventClass:
|
||||
@ -191,9 +191,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Event)
|
||||
if (tmp->mEventIsInternal) {
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->target)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->currentTarget)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->originalTarget)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->mTarget)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->mCurrentTarget)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEvent->mOriginalTarget)
|
||||
switch (tmp->mEvent->mClass) {
|
||||
case eMouseEventClass:
|
||||
case eMouseScrollEventClass:
|
||||
@ -258,8 +258,8 @@ Event::IsChrome(JSContext* aCx) const
|
||||
NS_METHOD
|
||||
Event::GetType(nsAString& aType)
|
||||
{
|
||||
if (!mIsMainThreadEvent || !mEvent->typeString.IsEmpty()) {
|
||||
aType = mEvent->typeString;
|
||||
if (!mIsMainThreadEvent || !mEvent->mSpecifiedEventTypeString.IsEmpty()) {
|
||||
aType = mEvent->mSpecifiedEventTypeString;
|
||||
return NS_OK;
|
||||
}
|
||||
const char* name = GetEventName(mEvent->mMessage);
|
||||
@ -267,9 +267,11 @@ Event::GetType(nsAString& aType)
|
||||
if (name) {
|
||||
CopyASCIItoUTF16(name, aType);
|
||||
return NS_OK;
|
||||
} else if (mEvent->mMessage == eUnidentifiedEvent && mEvent->userType) {
|
||||
aType = Substring(nsDependentAtomString(mEvent->userType), 2); // Remove "on"
|
||||
mEvent->typeString = aType;
|
||||
} else if (mEvent->mMessage == eUnidentifiedEvent &&
|
||||
mEvent->mSpecifiedEventType) {
|
||||
// Remove "on"
|
||||
aType = Substring(nsDependentAtomString(mEvent->mSpecifiedEventType), 2);
|
||||
mEvent->mSpecifiedEventTypeString = aType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -286,7 +288,7 @@ GetDOMEventTarget(nsIDOMEventTarget* aTarget)
|
||||
EventTarget*
|
||||
Event::GetTarget() const
|
||||
{
|
||||
return GetDOMEventTarget(mEvent->target);
|
||||
return GetDOMEventTarget(mEvent->mTarget);
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
@ -299,7 +301,7 @@ Event::GetTarget(nsIDOMEventTarget** aTarget)
|
||||
EventTarget*
|
||||
Event::GetCurrentTarget() const
|
||||
{
|
||||
return GetDOMEventTarget(mEvent->currentTarget);
|
||||
return GetDOMEventTarget(mEvent->mCurrentTarget);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -317,7 +319,7 @@ Event::GetTargetFromFrame()
|
||||
{
|
||||
if (!mPresContext) { return nullptr; }
|
||||
|
||||
// Get the target frame (have to get the ESM first)
|
||||
// Get the mTarget frame (have to get the ESM first)
|
||||
nsIFrame* targetFrame = mPresContext->EventStateManager()->GetEventTarget();
|
||||
if (!targetFrame) { return nullptr; }
|
||||
|
||||
@ -346,8 +348,8 @@ Event::GetExplicitOriginalTarget(nsIDOMEventTarget** aRealEventTarget)
|
||||
EventTarget*
|
||||
Event::GetOriginalTarget() const
|
||||
{
|
||||
if (mEvent->originalTarget) {
|
||||
return GetDOMEventTarget(mEvent->originalTarget);
|
||||
if (mEvent->mOriginalTarget) {
|
||||
return GetDOMEventTarget(mEvent->mOriginalTarget);
|
||||
}
|
||||
|
||||
return GetTarget();
|
||||
@ -421,8 +423,8 @@ Event::EventPhase() const
|
||||
{
|
||||
// Note, remember to check that this works also
|
||||
// if or when Bug 235441 is fixed.
|
||||
if ((mEvent->currentTarget &&
|
||||
mEvent->currentTarget == mEvent->target) ||
|
||||
if ((mEvent->mCurrentTarget &&
|
||||
mEvent->mCurrentTarget == mEvent->mTarget) ||
|
||||
mEvent->mFlags.InTargetPhase()) {
|
||||
return nsIDOMEvent::AT_TARGET;
|
||||
}
|
||||
@ -530,9 +532,10 @@ Event::PreventDefaultInternal(bool aCalledByDefaultHandler)
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(mEvent->currentTarget);
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(mEvent->mCurrentTarget);
|
||||
if (!node) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> win = do_QueryInterface(mEvent->currentTarget);
|
||||
nsCOMPtr<nsPIDOMWindowOuter> win =
|
||||
do_QueryInterface(mEvent->mCurrentTarget);
|
||||
if (!win) {
|
||||
return;
|
||||
}
|
||||
@ -547,14 +550,14 @@ void
|
||||
Event::SetEventType(const nsAString& aEventTypeArg)
|
||||
{
|
||||
if (mIsMainThreadEvent) {
|
||||
mEvent->typeString.Truncate();
|
||||
mEvent->userType =
|
||||
mEvent->mSpecifiedEventTypeString.Truncate();
|
||||
mEvent->mSpecifiedEventType =
|
||||
nsContentUtils::GetEventMessageAndAtom(aEventTypeArg, mEvent->mClass,
|
||||
&(mEvent->mMessage));
|
||||
} else {
|
||||
mEvent->userType = nullptr;
|
||||
mEvent->mSpecifiedEventType = nullptr;
|
||||
mEvent->mMessage = eUnidentifiedEvent;
|
||||
mEvent->typeString = aEventTypeArg;
|
||||
mEvent->mSpecifiedEventTypeString = aEventTypeArg;
|
||||
}
|
||||
}
|
||||
|
||||
@ -584,8 +587,8 @@ Event::InitEvent(const nsAString& aEventTypeArg,
|
||||
|
||||
// Clearing the old targets, so that the event is targeted correctly when
|
||||
// re-dispatching it.
|
||||
mEvent->target = nullptr;
|
||||
mEvent->originalTarget = nullptr;
|
||||
mEvent->mTarget = nullptr;
|
||||
mEvent->mOriginalTarget = nullptr;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -607,7 +610,7 @@ Event::DuplicatePrivateData()
|
||||
NS_IMETHODIMP
|
||||
Event::SetTarget(nsIDOMEventTarget* aTarget)
|
||||
{
|
||||
mEvent->target = do_QueryInterface(aTarget);
|
||||
mEvent->mTarget = do_QueryInterface(aTarget);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -989,10 +992,10 @@ Event::GetOffsetCoords(nsPresContext* aPresContext,
|
||||
LayoutDeviceIntPoint aPoint,
|
||||
CSSIntPoint aDefaultPoint)
|
||||
{
|
||||
if (!aEvent->target) {
|
||||
if (!aEvent->mTarget) {
|
||||
return GetPageCoords(aPresContext, aEvent, aPoint, aDefaultPoint);
|
||||
}
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aEvent->target);
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aEvent->mTarget);
|
||||
if (!content || !aPresContext) {
|
||||
return CSSIntPoint(0, 0);
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ public:
|
||||
MOZ_ASSERT(aOverridingMessage != eUnidentifiedEvent,
|
||||
"Only use this class with a valid overriding EventMessage");
|
||||
MOZ_ASSERT(mOrigMessage != eUnidentifiedEvent &&
|
||||
mEvent->mEvent->typeString.IsEmpty(),
|
||||
mEvent->mEvent->mSpecifiedEventTypeString.IsEmpty(),
|
||||
"Only use this class on events whose overridden type is "
|
||||
"known (so we can restore it properly)");
|
||||
|
||||
|
@ -259,13 +259,13 @@ public:
|
||||
mManager = mTarget->GetExistingListenerManager();
|
||||
}
|
||||
if (mManager) {
|
||||
NS_ASSERTION(aVisitor.mEvent->currentTarget == nullptr,
|
||||
NS_ASSERTION(aVisitor.mEvent->mCurrentTarget == nullptr,
|
||||
"CurrentTarget should be null!");
|
||||
mManager->HandleEvent(aVisitor.mPresContext, aVisitor.mEvent,
|
||||
&aVisitor.mDOMEvent,
|
||||
CurrentTarget(),
|
||||
&aVisitor.mEventStatus);
|
||||
NS_ASSERTION(aVisitor.mEvent->currentTarget == nullptr,
|
||||
NS_ASSERTION(aVisitor.mEvent->mCurrentTarget == nullptr,
|
||||
"CurrentTarget should be null!");
|
||||
}
|
||||
}
|
||||
@ -333,7 +333,7 @@ EventTargetChainItem::HandleEventTargetChain(
|
||||
ELMCreationDetector& aCd)
|
||||
{
|
||||
// Save the target so that it can be restored later.
|
||||
nsCOMPtr<EventTarget> firstTarget = aVisitor.mEvent->target;
|
||||
nsCOMPtr<EventTarget> firstTarget = aVisitor.mEvent->mTarget;
|
||||
uint32_t chainLength = aChain.Length();
|
||||
|
||||
// Capture
|
||||
@ -353,7 +353,7 @@ EventTargetChainItem::HandleEventTargetChain(
|
||||
uint32_t childIndex = j - 1;
|
||||
EventTarget* newTarget = aChain[childIndex].GetNewTarget();
|
||||
if (newTarget) {
|
||||
aVisitor.mEvent->target = newTarget;
|
||||
aVisitor.mEvent->mTarget = newTarget;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -380,7 +380,7 @@ EventTargetChainItem::HandleEventTargetChain(
|
||||
if (newTarget) {
|
||||
// Item is at anonymous boundary. Need to retarget for the current item
|
||||
// and for parent items.
|
||||
aVisitor.mEvent->target = newTarget;
|
||||
aVisitor.mEvent->mTarget = newTarget;
|
||||
}
|
||||
|
||||
if (aVisitor.mEvent->mFlags.mBubbles || newTarget) {
|
||||
@ -403,7 +403,7 @@ EventTargetChainItem::HandleEventTargetChain(
|
||||
aVisitor.mEvent->mFlags.mImmediatePropagationStopped = false;
|
||||
|
||||
// Setting back the original target of the event.
|
||||
aVisitor.mEvent->target = aVisitor.mEvent->originalTarget;
|
||||
aVisitor.mEvent->mTarget = aVisitor.mEvent->mOriginalTarget;
|
||||
|
||||
// Special handling if PresShell (or some other caller)
|
||||
// used a callback object.
|
||||
@ -413,7 +413,7 @@ EventTargetChainItem::HandleEventTargetChain(
|
||||
|
||||
// Retarget for system event group (which does the default handling too).
|
||||
// Setting back the target which was used also for default event group.
|
||||
aVisitor.mEvent->target = firstTarget;
|
||||
aVisitor.mEvent->mTarget = firstTarget;
|
||||
aVisitor.mEvent->mFlags.mInSystemGroup = true;
|
||||
HandleEventTargetChain(aChain,
|
||||
aVisitor,
|
||||
@ -515,7 +515,7 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
|
||||
do_QueryInterface(content->FindFirstNonChromeOnlyAccessContent());
|
||||
NS_ENSURE_STATE(newTarget);
|
||||
|
||||
aEvent->originalTarget = target;
|
||||
aEvent->mOriginalTarget = target;
|
||||
target = newTarget;
|
||||
retargeted = true;
|
||||
}
|
||||
@ -532,7 +532,7 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
|
||||
}
|
||||
|
||||
// Set the target to be the original dispatch target,
|
||||
aEvent->target = target;
|
||||
aEvent->mTarget = target;
|
||||
// but use chrome event handler or TabChildGlobal for event target chain.
|
||||
target = piTarget;
|
||||
} else if (NS_WARN_IF(!doc)) {
|
||||
@ -590,30 +590,30 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
|
||||
|
||||
// Make sure that nsIDOMEvent::target and nsIDOMEvent::originalTarget
|
||||
// point to the last item in the chain.
|
||||
if (!aEvent->target) {
|
||||
if (!aEvent->mTarget) {
|
||||
// Note, CurrentTarget() points always to the object returned by
|
||||
// GetTargetForEventTargetChain().
|
||||
aEvent->target = targetEtci->CurrentTarget();
|
||||
aEvent->mTarget = targetEtci->CurrentTarget();
|
||||
} else {
|
||||
// XXX But if the target is already set, use that. This is a hack
|
||||
// for the 'load', 'beforeunload' and 'unload' events,
|
||||
// which are dispatched to |window| but have document as their target.
|
||||
//
|
||||
// Make sure that the event target points to the right object.
|
||||
aEvent->target = aEvent->target->GetTargetForEventTargetChain();
|
||||
NS_ENSURE_STATE(aEvent->target);
|
||||
aEvent->mTarget = aEvent->mTarget->GetTargetForEventTargetChain();
|
||||
NS_ENSURE_STATE(aEvent->mTarget);
|
||||
}
|
||||
|
||||
if (retargeted) {
|
||||
aEvent->originalTarget =
|
||||
aEvent->originalTarget->GetTargetForEventTargetChain();
|
||||
NS_ENSURE_STATE(aEvent->originalTarget);
|
||||
aEvent->mOriginalTarget =
|
||||
aEvent->mOriginalTarget->GetTargetForEventTargetChain();
|
||||
NS_ENSURE_STATE(aEvent->mOriginalTarget);
|
||||
}
|
||||
else {
|
||||
aEvent->originalTarget = aEvent->target;
|
||||
aEvent->mOriginalTarget = aEvent->mTarget;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aEvent->originalTarget);
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aEvent->mOriginalTarget);
|
||||
bool isInAnon = (content && (content->IsInAnonymousSubtree() ||
|
||||
content->IsInShadowTree()));
|
||||
|
||||
@ -637,7 +637,7 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
|
||||
if (preVisitor.mCanHandle) {
|
||||
// At least the original target can handle the event.
|
||||
// Setting the retarget to the |target| simplifies retargeting code.
|
||||
nsCOMPtr<EventTarget> t = do_QueryInterface(aEvent->target);
|
||||
nsCOMPtr<EventTarget> t = do_QueryInterface(aEvent->mTarget);
|
||||
targetEtci->SetNewTarget(t);
|
||||
EventTargetChainItem* topEtci = targetEtci;
|
||||
targetEtci = nullptr;
|
||||
@ -655,7 +655,7 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
|
||||
if (preVisitor.mEventTargetAtParent) {
|
||||
// Need to set the target of the event
|
||||
// so that also the next retargeting works.
|
||||
preVisitor.mEvent->target = preVisitor.mEventTargetAtParent;
|
||||
preVisitor.mEvent->mTarget = preVisitor.mEventTargetAtParent;
|
||||
parentEtci->SetNewTarget(preVisitor.mEventTargetAtParent);
|
||||
}
|
||||
|
||||
@ -750,8 +750,8 @@ EventDispatcher::DispatchDOMEvent(nsISupports* aTarget,
|
||||
|
||||
bool dontResetTrusted = false;
|
||||
if (innerEvent->mFlags.mDispatchedAtLeastOnce) {
|
||||
innerEvent->target = nullptr;
|
||||
innerEvent->originalTarget = nullptr;
|
||||
innerEvent->mTarget = nullptr;
|
||||
innerEvent->mOriginalTarget = nullptr;
|
||||
} else {
|
||||
aDOMEvent->GetIsTrusted(&dontResetTrusted);
|
||||
}
|
||||
|
@ -240,8 +240,8 @@ public:
|
||||
* aEvent is used as the target (unless there is event
|
||||
* retargeting) and the originalTarget of the DOM Event.
|
||||
* aTarget is always used as the starting point for constructing the event
|
||||
* target chain, no matter what the value of aEvent->target is.
|
||||
* In other words, aEvent->target is only a property of the event and it has
|
||||
* target chain, no matter what the value of aEvent->mTarget is.
|
||||
* In other words, aEvent->mTarget is only a property of the event and it has
|
||||
* nothing to do with the construction of the event target chain.
|
||||
* Neither aTarget nor aEvent is allowed to be nullptr.
|
||||
*
|
||||
|
@ -674,9 +674,9 @@ EventListenerManager::ListenerCanHandle(const Listener* aListener,
|
||||
}
|
||||
if (aEvent->mMessage == eUnidentifiedEvent) {
|
||||
if (mIsMainThreadELM) {
|
||||
return aListener->mTypeAtom == aEvent->userType;
|
||||
return aListener->mTypeAtom == aEvent->mSpecifiedEventType;
|
||||
}
|
||||
return aListener->mTypeString.Equals(aEvent->typeString);
|
||||
return aListener->mTypeString.Equals(aEvent->mSpecifiedEventTypeString);
|
||||
}
|
||||
MOZ_ASSERT(mIsMainThreadELM);
|
||||
return aListener->mEventMessage == aEventMessage;
|
||||
@ -1225,16 +1225,16 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
||||
if (!*aDOMEvent) {
|
||||
// This is tiny bit slow, but happens only once per event.
|
||||
nsCOMPtr<EventTarget> et =
|
||||
do_QueryInterface(aEvent->originalTarget);
|
||||
do_QueryInterface(aEvent->mOriginalTarget);
|
||||
RefPtr<Event> event = EventDispatcher::CreateEvent(et, aPresContext,
|
||||
aEvent,
|
||||
EmptyString());
|
||||
event.forget(aDOMEvent);
|
||||
}
|
||||
if (*aDOMEvent) {
|
||||
if (!aEvent->currentTarget) {
|
||||
aEvent->currentTarget = aCurrentTarget->GetTargetForDOMEvent();
|
||||
if (!aEvent->currentTarget) {
|
||||
if (!aEvent->mCurrentTarget) {
|
||||
aEvent->mCurrentTarget = aCurrentTarget->GetTargetForDOMEvent();
|
||||
if (!aEvent->mCurrentTarget) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1300,11 +1300,11 @@ EventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
||||
usingLegacyMessage = true;
|
||||
}
|
||||
|
||||
aEvent->currentTarget = nullptr;
|
||||
aEvent->mCurrentTarget = nullptr;
|
||||
|
||||
if (mIsMainThreadELM && !hasListener) {
|
||||
mNoListenerForEvent = aEvent->mMessage;
|
||||
mNoListenerForEventAtom = aEvent->userType;
|
||||
mNoListenerForEventAtom = aEvent->mSpecifiedEventType;
|
||||
}
|
||||
|
||||
if (aEvent->DefaultPrevented()) {
|
||||
|
@ -343,7 +343,7 @@ public:
|
||||
// Check if we already know that there is no event listener for the event.
|
||||
if (mNoListenerForEvent == aEvent->mMessage &&
|
||||
(mNoListenerForEvent != eUnidentifiedEvent ||
|
||||
mNoListenerForEventAtom == aEvent->userType)) {
|
||||
mNoListenerForEventAtom == aEvent->mSpecifiedEventType)) {
|
||||
return;
|
||||
}
|
||||
HandleEventInternal(aPresContext, aEvent, aDOMEvent, aCurrentTarget,
|
||||
|
@ -582,9 +582,10 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
||||
aEvent->mClass == eWheelEventClass) &&
|
||||
!sIsPointerLocked) {
|
||||
sLastScreenPoint =
|
||||
Event::GetScreenCoords(aPresContext, aEvent, aEvent->refPoint);
|
||||
Event::GetScreenCoords(aPresContext, aEvent, aEvent->mRefPoint);
|
||||
sLastClientPoint =
|
||||
Event::GetClientCoords(aPresContext, aEvent, aEvent->refPoint, CSSIntPoint(0, 0));
|
||||
Event::GetClientCoords(aPresContext, aEvent, aEvent->mRefPoint,
|
||||
CSSIntPoint(0, 0));
|
||||
}
|
||||
|
||||
*aStatus = nsEventStatus_eIgnore;
|
||||
@ -1591,7 +1592,7 @@ EventStateManager::BeginTrackingDragGesture(nsPresContext* aPresContext,
|
||||
// Note that |inDownEvent| could be either a mouse down event or a
|
||||
// synthesized mouse move event.
|
||||
mGestureDownPoint =
|
||||
inDownEvent->refPoint + inDownEvent->mWidget->WidgetToScreenOffset();
|
||||
inDownEvent->mRefPoint + inDownEvent->mWidget->WidgetToScreenOffset();
|
||||
|
||||
if (inDownFrame) {
|
||||
inDownFrame->GetContentForEvent(inDownEvent,
|
||||
@ -1640,7 +1641,7 @@ EventStateManager::FillInEventFromGestureDown(WidgetMouseEvent* aEvent)
|
||||
// Set the coordinates in the new event to the coordinates of
|
||||
// the old event, adjusted for the fact that the widget might be
|
||||
// different
|
||||
aEvent->refPoint =
|
||||
aEvent->mRefPoint =
|
||||
mGestureDownPoint - aEvent->mWidget->WidgetToScreenOffset();
|
||||
aEvent->mModifiers = mGestureModifiers;
|
||||
aEvent->buttons = mGestureDownButtons;
|
||||
@ -1698,7 +1699,7 @@ EventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
||||
|
||||
// fire drag gesture if mouse has moved enough
|
||||
LayoutDeviceIntPoint pt =
|
||||
aEvent->refPoint + aEvent->mWidget->WidgetToScreenOffset();
|
||||
aEvent->mRefPoint + aEvent->mWidget->WidgetToScreenOffset();
|
||||
LayoutDeviceIntPoint distance = pt - mGestureDownPoint;
|
||||
if (Abs(distance.x) > AssertedCast<uint32_t>(pixelThresholdX) ||
|
||||
Abs(distance.y) > AssertedCast<uint32_t>(pixelThresholdY)) {
|
||||
@ -2301,7 +2302,7 @@ EventStateManager::SendLineScrollEvent(nsIFrame* aTargetFrame,
|
||||
eLegacyMouseLineOrPageScroll, aEvent->mWidget);
|
||||
event.mFlags.mDefaultPrevented = aState.mDefaultPrevented;
|
||||
event.mFlags.mDefaultPreventedByContent = aState.mDefaultPreventedByContent;
|
||||
event.refPoint = aEvent->refPoint;
|
||||
event.mRefPoint = aEvent->mRefPoint;
|
||||
event.mTime = aEvent->mTime;
|
||||
event.mTimeStamp = aEvent->mTimeStamp;
|
||||
event.mModifiers = aEvent->mModifiers;
|
||||
@ -2340,7 +2341,7 @@ EventStateManager::SendPixelScrollEvent(nsIFrame* aTargetFrame,
|
||||
eLegacyMousePixelScroll, aEvent->mWidget);
|
||||
event.mFlags.mDefaultPrevented = aState.mDefaultPrevented;
|
||||
event.mFlags.mDefaultPreventedByContent = aState.mDefaultPreventedByContent;
|
||||
event.refPoint = aEvent->refPoint;
|
||||
event.mRefPoint = aEvent->mRefPoint;
|
||||
event.mTime = aEvent->mTime;
|
||||
event.mTimeStamp = aEvent->mTimeStamp;
|
||||
event.mModifiers = aEvent->mModifiers;
|
||||
@ -2941,19 +2942,19 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
// we click on a visibility: none element.
|
||||
// We can't use nsIContent::IsFocusable() because we want to blur when
|
||||
// we click on a non-focusable element like a <div>.
|
||||
// We have to use |aEvent->target| to not make sure we do not check an
|
||||
// anonymous node of the targeted element.
|
||||
// We have to use |aEvent->mTarget| to not make sure we do not check
|
||||
// an anonymous node of the targeted element.
|
||||
suppressBlur = (ui->mUserFocus == NS_STYLE_USER_FOCUS_IGNORE);
|
||||
|
||||
if (!suppressBlur) {
|
||||
nsCOMPtr<Element> element = do_QueryInterface(aEvent->target);
|
||||
nsCOMPtr<Element> element = do_QueryInterface(aEvent->mTarget);
|
||||
suppressBlur = element &&
|
||||
element->State().HasState(NS_EVENT_STATE_DISABLED);
|
||||
}
|
||||
|
||||
if (!suppressBlur) {
|
||||
nsCOMPtr<nsIDOMXULControlElement> xulControl =
|
||||
do_QueryInterface(aEvent->target);
|
||||
do_QueryInterface(aEvent->mTarget);
|
||||
if (xulControl) {
|
||||
bool disabled;
|
||||
xulControl->GetDisabled(&disabled);
|
||||
@ -3424,11 +3425,11 @@ EventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
WidgetDragEvent event(aEvent->IsTrusted(), eLegacyDragDrop, widget);
|
||||
|
||||
WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
|
||||
event.refPoint = mouseEvent->refPoint;
|
||||
event.mRefPoint = mouseEvent->mRefPoint;
|
||||
if (mouseEvent->mWidget) {
|
||||
event.refPoint += mouseEvent->mWidget->WidgetToScreenOffset();
|
||||
event.mRefPoint += mouseEvent->mWidget->WidgetToScreenOffset();
|
||||
}
|
||||
event.refPoint -= widget->WidgetToScreenOffset();
|
||||
event.mRefPoint -= widget->WidgetToScreenOffset();
|
||||
event.mModifiers = mouseEvent->mModifiers;
|
||||
event.buttons = mouseEvent->buttons;
|
||||
event.inputSource = mouseEvent->inputSource;
|
||||
@ -3865,7 +3866,7 @@ CreateMouseOrPointerWidgetEvent(WidgetMouseEvent* aMouseEvent,
|
||||
aMouseEvent->mWidget, WidgetMouseEvent::eReal);
|
||||
aNewEvent->relatedTarget = aRelatedContent;
|
||||
}
|
||||
aNewEvent->refPoint = aMouseEvent->refPoint;
|
||||
aNewEvent->mRefPoint = aMouseEvent->mRefPoint;
|
||||
aNewEvent->mModifiers = aMouseEvent->mModifiers;
|
||||
aNewEvent->button = aMouseEvent->button;
|
||||
aNewEvent->buttons = aMouseEvent->buttons;
|
||||
@ -4206,7 +4207,7 @@ EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent)
|
||||
{
|
||||
// Mouse movement is reported on the MouseEvent.movement{X,Y} fields.
|
||||
// Movement is calculated in UIEvent::GetMovementPoint() as:
|
||||
// previous_mousemove_refPoint - current_mousemove_refPoint.
|
||||
// previous_mousemove_mRefPoint - current_mousemove_mRefPoint.
|
||||
if (sIsPointerLocked && aMouseEvent->mWidget) {
|
||||
// The pointer is locked. If the pointer is not located at the center of
|
||||
// the window, dispatch a synthetic mousemove to return the pointer there.
|
||||
@ -4216,8 +4217,8 @@ EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent)
|
||||
// dispatching the centering move event to content.
|
||||
LayoutDeviceIntPoint center =
|
||||
GetWindowClientRectCenter(aMouseEvent->mWidget);
|
||||
aMouseEvent->lastRefPoint = center;
|
||||
if (aMouseEvent->refPoint != center) {
|
||||
aMouseEvent->mLastRefPoint = center;
|
||||
if (aMouseEvent->mRefPoint != center) {
|
||||
// Mouse move doesn't finish at the center of the window. Dispatch a
|
||||
// synthetic native mouse event to move the pointer back to the center
|
||||
// of the window, to faciliate more movement. But first, record that
|
||||
@ -4226,7 +4227,7 @@ EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent)
|
||||
sSynthCenteringPoint = center;
|
||||
aMouseEvent->mWidget->SynthesizeNativeMouseMove(
|
||||
center + aMouseEvent->mWidget->WidgetToScreenOffset(), nullptr);
|
||||
} else if (aMouseEvent->refPoint == sSynthCenteringPoint) {
|
||||
} else if (aMouseEvent->mRefPoint == sSynthCenteringPoint) {
|
||||
// This is the "synthetic native" event we dispatched to re-center the
|
||||
// pointer. Cancel it so we don't expose the centering move to content.
|
||||
aMouseEvent->StopPropagation();
|
||||
@ -4235,17 +4236,17 @@ EventStateManager::GenerateMouseEnterExit(WidgetMouseEvent* aMouseEvent)
|
||||
sSynthCenteringPoint = kInvalidRefPoint;
|
||||
}
|
||||
} else if (sLastRefPoint == kInvalidRefPoint) {
|
||||
// We don't have a valid previous mousemove refPoint. This is either
|
||||
// We don't have a valid previous mousemove mRefPoint. This is either
|
||||
// the first move we've encountered, or the mouse has just re-entered
|
||||
// the application window. We should report (0,0) movement for this
|
||||
// case, so make the current and previous refPoints the same.
|
||||
aMouseEvent->lastRefPoint = aMouseEvent->refPoint;
|
||||
// case, so make the current and previous mRefPoints the same.
|
||||
aMouseEvent->mLastRefPoint = aMouseEvent->mRefPoint;
|
||||
} else {
|
||||
aMouseEvent->lastRefPoint = sLastRefPoint;
|
||||
aMouseEvent->mLastRefPoint = sLastRefPoint;
|
||||
}
|
||||
|
||||
// Update the last known refPoint with the current refPoint.
|
||||
sLastRefPoint = aMouseEvent->refPoint;
|
||||
// Update the last known mRefPoint with the current mRefPoint.
|
||||
sLastRefPoint = aMouseEvent->mRefPoint;
|
||||
}
|
||||
MOZ_FALLTHROUGH;
|
||||
case ePointerMove:
|
||||
@ -4474,7 +4475,7 @@ EventStateManager::FireDragEnterOrExit(nsPresContext* aPresContext,
|
||||
{
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
WidgetDragEvent event(aDragEvent->IsTrusted(), aMessage, aDragEvent->mWidget);
|
||||
event.refPoint = aDragEvent->refPoint;
|
||||
event.mRefPoint = aDragEvent->mRefPoint;
|
||||
event.mModifiers = aDragEvent->mModifiers;
|
||||
event.buttons = aDragEvent->buttons;
|
||||
event.relatedTarget = aRelatedTarget;
|
||||
@ -4638,7 +4639,7 @@ EventStateManager::CheckForAndDispatchClick(WidgetMouseEvent* aEvent,
|
||||
|
||||
WidgetMouseEvent event(aEvent->IsTrusted(), eMouseClick,
|
||||
aEvent->mWidget, WidgetMouseEvent::eReal);
|
||||
event.refPoint = aEvent->refPoint;
|
||||
event.mRefPoint = aEvent->mRefPoint;
|
||||
event.clickCount = aEvent->clickCount;
|
||||
event.mModifiers = aEvent->mModifiers;
|
||||
event.buttons = aEvent->buttons;
|
||||
@ -4672,7 +4673,7 @@ EventStateManager::CheckForAndDispatchClick(WidgetMouseEvent* aEvent,
|
||||
//fire double click
|
||||
WidgetMouseEvent event2(aEvent->IsTrusted(), eMouseDoubleClick,
|
||||
aEvent->mWidget, WidgetMouseEvent::eReal);
|
||||
event2.refPoint = aEvent->refPoint;
|
||||
event2.mRefPoint = aEvent->mRefPoint;
|
||||
event2.clickCount = aEvent->clickCount;
|
||||
event2.mModifiers = aEvent->mModifiers;
|
||||
event2.buttons = aEvent->buttons;
|
||||
|
@ -907,12 +907,12 @@ private:
|
||||
int32_t mLockCursor;
|
||||
bool mLastFrameConsumedSetCursor;
|
||||
|
||||
// Last mouse event refPoint (the offset from the widget's origin in
|
||||
// Last mouse event mRefPoint (the offset from the widget's origin in
|
||||
// device pixels) when mouse was locked, used to restore mouse position
|
||||
// after unlocking.
|
||||
LayoutDeviceIntPoint mPreLockPoint;
|
||||
|
||||
// Stores the refPoint of the last synthetic mouse move we dispatched
|
||||
// Stores the mRefPoint of the last synthetic mouse move we dispatched
|
||||
// to re-center the mouse when we were pointer locked. If this is (-1,-1) it
|
||||
// means we've not recently dispatched a centering event. We use this to
|
||||
// detect when we receive the synth event, so we can cancel and not send it
|
||||
@ -923,7 +923,7 @@ private:
|
||||
nsCOMPtr<nsIContent> mCurrentTargetContent;
|
||||
static nsWeakFrame sLastDragOverFrame;
|
||||
|
||||
// Stores the refPoint (the offset from the widget's origin in device
|
||||
// Stores the mRefPoint (the offset from the widget's origin in device
|
||||
// pixels) of the last mouse event.
|
||||
static LayoutDeviceIntPoint sLastRefPoint;
|
||||
|
||||
|
@ -777,7 +777,7 @@ IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext,
|
||||
|
||||
WidgetQueryContentEvent charAtPt(true, eQueryCharacterAtPoint,
|
||||
aMouseEvent->mWidget);
|
||||
charAtPt.refPoint = aMouseEvent->refPoint;
|
||||
charAtPt.mRefPoint = aMouseEvent->mRefPoint;
|
||||
ContentEventHandler handler(aPresContext);
|
||||
handler.OnQueryCharacterAtPoint(&charAtPt);
|
||||
if (NS_WARN_IF(!charAtPt.mSucceeded) ||
|
||||
@ -802,7 +802,7 @@ IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext,
|
||||
// The refPt is relative to its widget.
|
||||
// We should notify it with offset in the widget.
|
||||
if (aMouseEvent->mWidget != mWidget) {
|
||||
charAtPt.refPoint += aMouseEvent->mWidget->WidgetToScreenOffset() -
|
||||
charAtPt.mRefPoint += aMouseEvent->mWidget->WidgetToScreenOffset() -
|
||||
mWidget->WidgetToScreenOffset();
|
||||
}
|
||||
|
||||
@ -810,7 +810,7 @@ IMEContentObserver::OnMouseButtonEvent(nsPresContext* aPresContext,
|
||||
notification.mMouseButtonEventData.mEventMessage = aMouseEvent->mMessage;
|
||||
notification.mMouseButtonEventData.mOffset = charAtPt.mReply.mOffset;
|
||||
notification.mMouseButtonEventData.mCursorPos.Set(
|
||||
charAtPt.refPoint.ToUnknownPoint());
|
||||
charAtPt.mRefPoint.ToUnknownPoint());
|
||||
notification.mMouseButtonEventData.mCharRect.Set(
|
||||
charAtPt.mReply.mRect.ToUnknownRect());
|
||||
notification.mMouseButtonEventData.mButton = aMouseEvent->button;
|
||||
|
@ -32,7 +32,7 @@ MouseEvent::MouseEvent(EventTarget* aOwner,
|
||||
else {
|
||||
mEventIsInternal = true;
|
||||
mEvent->mTime = PR_Now();
|
||||
mEvent->refPoint.x = mEvent->refPoint.y = 0;
|
||||
mEvent->mRefPoint = LayoutDeviceIntPoint(0, 0);
|
||||
mouseEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
|
||||
}
|
||||
|
||||
@ -82,8 +82,8 @@ MouseEvent::InitMouseEvent(const nsAString& aType,
|
||||
mouseEventBase->InitBasicModifiers(aCtrlKey, aAltKey, aShiftKey, aMetaKey);
|
||||
mClientPoint.x = aClientX;
|
||||
mClientPoint.y = aClientY;
|
||||
mouseEventBase->refPoint.x = aScreenX;
|
||||
mouseEventBase->refPoint.y = aScreenY;
|
||||
mouseEventBase->mRefPoint.x = aScreenX;
|
||||
mouseEventBase->mRefPoint.y = aScreenY;
|
||||
|
||||
WidgetMouseEvent* mouseEvent = mEvent->AsMouseEvent();
|
||||
if (mouseEvent) {
|
||||
@ -298,7 +298,8 @@ MouseEvent::GetRelatedTarget()
|
||||
|
||||
if (relatedTarget) {
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(relatedTarget);
|
||||
nsCOMPtr<nsIContent> currentTarget = do_QueryInterface(mEvent->currentTarget);
|
||||
nsCOMPtr<nsIContent> currentTarget =
|
||||
do_QueryInterface(mEvent->mCurrentTarget);
|
||||
|
||||
nsIContent* shadowRelatedTarget = GetShadowRelatedTarget(currentTarget, content);
|
||||
if (shadowRelatedTarget) {
|
||||
@ -357,7 +358,7 @@ MouseEvent::GetScreenX(int32_t* aScreenX)
|
||||
int32_t
|
||||
MouseEvent::ScreenX()
|
||||
{
|
||||
return Event::GetScreenCoords(mPresContext, mEvent, mEvent->refPoint).x;
|
||||
return Event::GetScreenCoords(mPresContext, mEvent, mEvent->mRefPoint).x;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -371,7 +372,7 @@ MouseEvent::GetScreenY(int32_t* aScreenY)
|
||||
int32_t
|
||||
MouseEvent::ScreenY()
|
||||
{
|
||||
return Event::GetScreenCoords(mPresContext, mEvent, mEvent->refPoint).y;
|
||||
return Event::GetScreenCoords(mPresContext, mEvent, mEvent->mRefPoint).y;
|
||||
}
|
||||
|
||||
|
||||
@ -386,7 +387,7 @@ MouseEvent::GetClientX(int32_t* aClientX)
|
||||
int32_t
|
||||
MouseEvent::ClientX()
|
||||
{
|
||||
return Event::GetClientCoords(mPresContext, mEvent, mEvent->refPoint,
|
||||
return Event::GetClientCoords(mPresContext, mEvent, mEvent->mRefPoint,
|
||||
mClientPoint).x;
|
||||
}
|
||||
|
||||
@ -401,21 +402,21 @@ MouseEvent::GetClientY(int32_t* aClientY)
|
||||
int32_t
|
||||
MouseEvent::ClientY()
|
||||
{
|
||||
return Event::GetClientCoords(mPresContext, mEvent, mEvent->refPoint,
|
||||
return Event::GetClientCoords(mPresContext, mEvent, mEvent->mRefPoint,
|
||||
mClientPoint).y;
|
||||
}
|
||||
|
||||
int32_t
|
||||
MouseEvent::OffsetX()
|
||||
{
|
||||
return Event::GetOffsetCoords(mPresContext, mEvent, mEvent->refPoint,
|
||||
return Event::GetOffsetCoords(mPresContext, mEvent, mEvent->mRefPoint,
|
||||
mClientPoint).x;
|
||||
}
|
||||
|
||||
int32_t
|
||||
MouseEvent::OffsetY()
|
||||
{
|
||||
return Event::GetOffsetCoords(mPresContext, mEvent, mEvent->refPoint,
|
||||
return Event::GetOffsetCoords(mPresContext, mEvent, mEvent->mRefPoint,
|
||||
mClientPoint).y;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ MouseScrollEvent::MouseScrollEvent(EventTarget* aOwner,
|
||||
} else {
|
||||
mEventIsInternal = true;
|
||||
mEvent->mTime = PR_Now();
|
||||
mEvent->refPoint.x = mEvent->refPoint.y = 0;
|
||||
mEvent->mRefPoint = LayoutDeviceIntPoint(0, 0);
|
||||
static_cast<WidgetMouseEventBase*>(mEvent)->inputSource =
|
||||
nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ PointerEvent::PointerEvent(EventTarget* aOwner,
|
||||
} else {
|
||||
mEventIsInternal = true;
|
||||
mEvent->mTime = PR_Now();
|
||||
mEvent->refPoint.x = mEvent->refPoint.y = 0;
|
||||
mEvent->mRefPoint = LayoutDeviceIntPoint(0, 0);
|
||||
mouseEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ SimpleGestureEvent::SimpleGestureEvent(EventTarget* aOwner,
|
||||
} else {
|
||||
mEventIsInternal = true;
|
||||
mEvent->mTime = PR_Now();
|
||||
mEvent->refPoint.x = mEvent->refPoint.y = 0;
|
||||
mEvent->mRefPoint = LayoutDeviceIntPoint(0, 0);
|
||||
static_cast<WidgetMouseEventBase*>(mEvent)->inputSource =
|
||||
nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ TouchEvent::TargetTouches()
|
||||
// touch that is ending
|
||||
if ((mEvent->mMessage != eTouchEnd && mEvent->mMessage != eTouchCancel) ||
|
||||
!touches[i]->mChanged) {
|
||||
if (touches[i]->mTarget == mEvent->originalTarget) {
|
||||
if (touches[i]->mTarget == mEvent->mOriginalTarget) {
|
||||
targetTouches.AppendElement(touches[i]);
|
||||
}
|
||||
}
|
||||
|
@ -130,8 +130,8 @@ UIEvent::GetMovementPoint()
|
||||
}
|
||||
|
||||
// Calculate the delta between the last screen point and the current one.
|
||||
nsIntPoint current = DevPixelsToCSSPixels(mEvent->refPoint, mPresContext);
|
||||
nsIntPoint last = DevPixelsToCSSPixels(mEvent->lastRefPoint, mPresContext);
|
||||
nsIntPoint current = DevPixelsToCSSPixels(mEvent->mRefPoint, mPresContext);
|
||||
nsIntPoint last = DevPixelsToCSSPixels(mEvent->mLastRefPoint, mPresContext);
|
||||
return current - last;
|
||||
}
|
||||
|
||||
@ -192,7 +192,7 @@ UIEvent::PageX() const
|
||||
return mPagePoint.x;
|
||||
}
|
||||
|
||||
return Event::GetPageCoords(mPresContext, mEvent, mEvent->refPoint,
|
||||
return Event::GetPageCoords(mPresContext, mEvent, mEvent->mRefPoint,
|
||||
mClientPoint).x;
|
||||
}
|
||||
|
||||
@ -211,7 +211,7 @@ UIEvent::PageY() const
|
||||
return mPagePoint.y;
|
||||
}
|
||||
|
||||
return Event::GetPageCoords(mPresContext, mEvent, mEvent->refPoint,
|
||||
return Event::GetPageCoords(mPresContext, mEvent, mEvent->mRefPoint,
|
||||
mClientPoint).y;
|
||||
}
|
||||
|
||||
@ -365,20 +365,20 @@ NS_IMETHODIMP
|
||||
UIEvent::DuplicatePrivateData()
|
||||
{
|
||||
mClientPoint =
|
||||
Event::GetClientCoords(mPresContext, mEvent, mEvent->refPoint,
|
||||
Event::GetClientCoords(mPresContext, mEvent, mEvent->mRefPoint,
|
||||
mClientPoint);
|
||||
mMovementPoint = GetMovementPoint();
|
||||
mLayerPoint = GetLayerPoint();
|
||||
mPagePoint =
|
||||
Event::GetPageCoords(mPresContext, mEvent, mEvent->refPoint, mClientPoint);
|
||||
// GetScreenPoint converts mEvent->refPoint to right coordinates.
|
||||
Event::GetPageCoords(mPresContext, mEvent, mEvent->mRefPoint, mClientPoint);
|
||||
// GetScreenPoint converts mEvent->mRefPoint to right coordinates.
|
||||
CSSIntPoint screenPoint =
|
||||
Event::GetScreenCoords(mPresContext, mEvent, mEvent->refPoint);
|
||||
Event::GetScreenCoords(mPresContext, mEvent, mEvent->mRefPoint);
|
||||
nsresult rv = Event::DuplicatePrivateData();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
CSSToLayoutDeviceScale scale = mPresContext ? mPresContext->CSSToDevPixelScale()
|
||||
: CSSToLayoutDeviceScale(1);
|
||||
mEvent->refPoint = RoundedToInt(screenPoint * scale);
|
||||
mEvent->mRefPoint = RoundedToInt(screenPoint * scale);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ protected:
|
||||
nsCOMPtr<nsPIDOMWindowOuter> mView;
|
||||
int32_t mDetail;
|
||||
CSSIntPoint mClientPoint;
|
||||
// Screenpoint is mEvent->refPoint.
|
||||
// Screenpoint is mEvent->mRefPoint.
|
||||
nsIntPoint mLayerPoint;
|
||||
CSSIntPoint mPagePoint;
|
||||
nsIntPoint mMovementPoint;
|
||||
|
@ -31,7 +31,7 @@ WheelEvent::WheelEvent(EventTarget* aOwner,
|
||||
} else {
|
||||
mEventIsInternal = true;
|
||||
mEvent->mTime = PR_Now();
|
||||
mEvent->refPoint.x = mEvent->refPoint.y = 0;
|
||||
mEvent->mRefPoint = LayoutDeviceIntPoint(0, 0);
|
||||
mEvent->AsWheelEvent()->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
@ -339,7 +339,7 @@ WheelTransaction::GetScreenPoint(WidgetGUIEvent* aEvent)
|
||||
{
|
||||
NS_ASSERTION(aEvent, "aEvent is null");
|
||||
NS_ASSERTION(aEvent->mWidget, "aEvent-mWidget is null");
|
||||
return (aEvent->refPoint + aEvent->mWidget->WidgetToScreenOffset())
|
||||
return (aEvent->mRefPoint + aEvent->mWidget->WidgetToScreenOffset())
|
||||
.ToUnknownPoint();
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1236979
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<style>
|
||||
@keyframes anim1 {
|
||||
0% { margin-left: 0px }
|
||||
100% { margin-left: 100px }
|
||||
0% { margin-left: 200px }
|
||||
100% { margin-left: 300px }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@ -31,21 +31,6 @@ SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// Array of info-bundles about each legacy event to be tested:
|
||||
var gLegacyEventInfo = [
|
||||
{
|
||||
legacy_name: "webkitTransitionEnd",
|
||||
modern_name: "transitionend",
|
||||
trigger_event: triggerShortTransition,
|
||||
},
|
||||
{
|
||||
legacy_name: "webkitAnimationStart",
|
||||
modern_name: "animationstart",
|
||||
trigger_event: triggerShortAnimation,
|
||||
},
|
||||
{
|
||||
legacy_name: "webkitAnimationEnd",
|
||||
modern_name: "animationend",
|
||||
trigger_event: triggerShortAnimation,
|
||||
},
|
||||
{
|
||||
legacy_name: "webkitAnimationIteration",
|
||||
modern_name: "animationiteration",
|
||||
@ -88,7 +73,8 @@ function triggerShortAnimation(node) {
|
||||
// away, and that we don't risk hitting the end of the second iteration at the
|
||||
// same time.
|
||||
function triggerAnimationIteration(node) {
|
||||
node.style.animation = "anim1 300s -299.999s linear 2";
|
||||
dump("************ Add Animation! **********");
|
||||
node.style.animation = "anim1 1s -0.999s linear 2";
|
||||
}
|
||||
|
||||
// GENERAL UTILITY FUNCTIONS
|
||||
@ -112,6 +98,7 @@ function createChildDiv(parentNode) {
|
||||
// the event-handler will invoke that callback as well.
|
||||
function createHandlerWithTypeCheck(expectedEventType, extraHandlerLogic) {
|
||||
var handler = function(e) {
|
||||
dump("********** event fired [" + e.type + "] ******\n");
|
||||
is(e.type, expectedEventType,
|
||||
"When an event handler for '" + expectedEventType + "' is invoked, " +
|
||||
"the event's type field should be '" + expectedEventType + "'.");
|
||||
@ -137,16 +124,19 @@ function mpTestLegacyEventSent(eventInfo) {
|
||||
function(resolve, reject) {
|
||||
// Create a node & register an event-handler for the legacy event:
|
||||
var div = createChildDiv();
|
||||
div.innerHTML = "<h2>Clobber</h2>";
|
||||
|
||||
var handler = createHandlerWithTypeCheck(eventInfo.legacy_name,
|
||||
function() {
|
||||
// When event-handler is done, clean up & resolve:
|
||||
div.parentNode.removeChild(div);
|
||||
dump("************ Resolved **********\n");
|
||||
resolve();
|
||||
});
|
||||
div.addEventListener(eventInfo.legacy_name, handler);
|
||||
|
||||
// Trigger the event:
|
||||
dump("************ trigger[" + eventInfo.legacy_name + "] **********\n");
|
||||
eventInfo.trigger_event(div);
|
||||
}
|
||||
);
|
||||
@ -174,6 +164,7 @@ function mpTestModernBeatsLegacy(eventInfo) {
|
||||
"both modern & legacy event type on the same node");
|
||||
// When event-handler is done, clean up & resolve:
|
||||
div.parentNode.removeChild(div);
|
||||
dump("************ Resolved **********\n");
|
||||
resolve();
|
||||
});
|
||||
|
||||
@ -221,6 +212,7 @@ function mpTestDiffListenersEventBubbling(eventInfo) {
|
||||
"Same event object should bubble, despite difference in type");
|
||||
// Clean up.
|
||||
grandparent.parentNode.removeChild(grandparent);
|
||||
dump("************ Resolved **********\n");
|
||||
resolve();
|
||||
}));
|
||||
|
||||
@ -270,6 +262,7 @@ function mpTestDiffListenersEventCapturing(eventInfo) {
|
||||
"Event should have fired on parent");
|
||||
// Clean up.
|
||||
grandparent.parentNode.removeChild(grandparent);
|
||||
dump("************ Resolved **********\n");
|
||||
resolve();
|
||||
}), true);
|
||||
|
||||
@ -281,14 +274,19 @@ function mpTestDiffListenersEventCapturing(eventInfo) {
|
||||
// MAIN FUNCTION: Kick off the tests.
|
||||
function main() {
|
||||
Promise.resolve().then(function() {
|
||||
dump("part1 clear\n");
|
||||
return Promise.all(gLegacyEventInfo.map(mpTestLegacyEventSent))
|
||||
}).then(function() {
|
||||
dump("part2 clear\n");
|
||||
return Promise.all(gLegacyEventInfo.map(mpTestModernBeatsLegacy));
|
||||
}).then(function() {
|
||||
dump("part3 clear");
|
||||
return Promise.all(gLegacyEventInfo.map(mpTestDiffListenersEventCapturing));
|
||||
}).then(function() {
|
||||
dump("part4 clear");
|
||||
return Promise.all(gLegacyEventInfo.map(mpTestDiffListenersEventBubbling));
|
||||
}).then(function() {
|
||||
dump("part5 clear");
|
||||
SimpleTest.finish();
|
||||
}).catch(function(reason) {
|
||||
ok(false, "Test failed: " + reason);
|
||||
|
@ -451,7 +451,7 @@ ExtractFromURLSearchParams(const URLSearchParams& aParams,
|
||||
nsAutoString serialized;
|
||||
aParams.Stringify(serialized);
|
||||
aContentType = NS_LITERAL_CSTRING("application/x-www-form-urlencoded;charset=UTF-8");
|
||||
return NS_NewStringInputStream(aStream, serialized);
|
||||
return NS_NewCStringInputStream(aStream, NS_ConvertUTF16toUTF8(serialized));
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -491,7 +491,7 @@ nsresult
|
||||
HTMLFormElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
||||
{
|
||||
aVisitor.mWantsWillHandleEvent = true;
|
||||
if (aVisitor.mEvent->originalTarget == static_cast<nsIContent*>(this)) {
|
||||
if (aVisitor.mEvent->mOriginalTarget == static_cast<nsIContent*>(this)) {
|
||||
uint32_t msg = aVisitor.mEvent->mMessage;
|
||||
if (msg == eFormSubmit) {
|
||||
if (mGeneratingSubmit) {
|
||||
@ -524,7 +524,7 @@ HTMLFormElement::WillHandleEvent(EventChainPostVisitor& aVisitor)
|
||||
if ((aVisitor.mEvent->mMessage == eFormSubmit ||
|
||||
aVisitor.mEvent->mMessage == eFormReset) &&
|
||||
aVisitor.mEvent->mFlags.mInBubblingPhase &&
|
||||
aVisitor.mEvent->originalTarget != static_cast<nsIContent*>(this)) {
|
||||
aVisitor.mEvent->mOriginalTarget != static_cast<nsIContent*>(this)) {
|
||||
aVisitor.mEvent->StopPropagation();
|
||||
}
|
||||
return NS_OK;
|
||||
@ -533,7 +533,7 @@ HTMLFormElement::WillHandleEvent(EventChainPostVisitor& aVisitor)
|
||||
nsresult
|
||||
HTMLFormElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
||||
{
|
||||
if (aVisitor.mEvent->originalTarget == static_cast<nsIContent*>(this)) {
|
||||
if (aVisitor.mEvent->mOriginalTarget == static_cast<nsIContent*>(this)) {
|
||||
EventMessage msg = aVisitor.mEvent->mMessage;
|
||||
if (msg == eFormSubmit) {
|
||||
// let the form know not to defer subsequent submissions
|
||||
|
@ -1157,8 +1157,16 @@ HTMLImageElement::UpdateResponsiveSource()
|
||||
/*static */ bool
|
||||
HTMLImageElement::SupportedPictureSourceType(const nsAString& aType)
|
||||
{
|
||||
nsAutoString type;
|
||||
nsAutoString params;
|
||||
|
||||
nsContentUtils::SplitMimeType(aType, type, params);
|
||||
if (type.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return
|
||||
imgLoader::SupportImageWithMimeType(NS_ConvertUTF16toUTF8(aType).get(),
|
||||
imgLoader::SupportImageWithMimeType(NS_ConvertUTF16toUTF8(type).get(),
|
||||
AcceptedMimeTypes::IMAGES_AND_DOCUMENTS);
|
||||
}
|
||||
|
||||
|
@ -3429,7 +3429,7 @@ HTMLInputElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
||||
// nsIContent::PreHandleEvent doesn't reset any change we make to mCanHandle.
|
||||
if (mType == NS_FORM_INPUT_NUMBER &&
|
||||
aVisitor.mEvent->IsTrusted() &&
|
||||
aVisitor.mEvent->originalTarget != this) {
|
||||
aVisitor.mEvent->mOriginalTarget != this) {
|
||||
// <input type=number> has an anonymous <input type=text> descendant. If
|
||||
// 'input' or 'change' events are fired at that text control then we need
|
||||
// to do some special handling here.
|
||||
@ -3439,7 +3439,7 @@ HTMLInputElement::PreHandleEvent(EventChainPreVisitor& aVisitor)
|
||||
if (numberControlFrame) {
|
||||
textControl = numberControlFrame->GetAnonTextControl();
|
||||
}
|
||||
if (textControl && aVisitor.mEvent->originalTarget == textControl) {
|
||||
if (textControl && aVisitor.mEvent->mOriginalTarget == textControl) {
|
||||
if (aVisitor.mEvent->mMessage == eEditorInput) {
|
||||
// Propogate the anon text control's new value to our HTMLInputElement:
|
||||
nsAutoString value;
|
||||
@ -3715,7 +3715,7 @@ HTMLInputElement::MaybeInitPickers(EventChainPostVisitor& aVisitor)
|
||||
// directory picker, else we open the file picker.
|
||||
FilePickerType type = FILE_PICKER_FILE;
|
||||
nsCOMPtr<nsIContent> target =
|
||||
do_QueryInterface(aVisitor.mEvent->originalTarget);
|
||||
do_QueryInterface(aVisitor.mEvent->mOriginalTarget);
|
||||
if (target &&
|
||||
target->GetParent() == this &&
|
||||
target->IsRootOfNativeAnonymousSubtree() &&
|
||||
@ -3782,7 +3782,7 @@ HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
||||
mType != NS_FORM_INPUT_NUMBER) {
|
||||
WidgetMouseEvent* mouseEvent = aVisitor.mEvent->AsMouseEvent();
|
||||
if (mouseEvent && mouseEvent->IsLeftClickEvent() &&
|
||||
!ShouldPreventDOMActivateDispatch(aVisitor.mEvent->originalTarget)) {
|
||||
!ShouldPreventDOMActivateDispatch(aVisitor.mEvent->mOriginalTarget)) {
|
||||
// DOMActive event should be trusted since the activation is actually
|
||||
// occurred even if the cause is an untrusted click event.
|
||||
InternalUIEvent actEvent(true, eLegacyDOMActivate, mouseEvent);
|
||||
|
@ -112,7 +112,7 @@ HTMLLabelElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> target = do_QueryInterface(aVisitor.mEvent->target);
|
||||
nsCOMPtr<nsIContent> target = do_QueryInterface(aVisitor.mEvent->mTarget);
|
||||
if (InInteractiveHTMLContent(target, this)) {
|
||||
return NS_OK;
|
||||
}
|
||||
@ -128,7 +128,7 @@ HTMLLabelElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
||||
// We reset the mouse-down point on every event because there is
|
||||
// no guarantee we will reach the eMouseClick code below.
|
||||
LayoutDeviceIntPoint* curPoint =
|
||||
new LayoutDeviceIntPoint(mouseEvent->refPoint);
|
||||
new LayoutDeviceIntPoint(mouseEvent->mRefPoint);
|
||||
SetProperty(nsGkAtoms::labelMouseDownPtProperty,
|
||||
static_cast<void*>(curPoint),
|
||||
nsINode::DeleteProperty<LayoutDeviceIntPoint>);
|
||||
@ -146,7 +146,7 @@ HTMLLabelElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
||||
LayoutDeviceIntPoint dragDistance = *mouseDownPoint;
|
||||
DeleteProperty(nsGkAtoms::labelMouseDownPtProperty);
|
||||
|
||||
dragDistance -= mouseEvent->refPoint;
|
||||
dragDistance -= mouseEvent->mRefPoint;
|
||||
const int CLICK_DISTANCE = 2;
|
||||
dragSelect = dragDistance.x > CLICK_DISTANCE ||
|
||||
dragDistance.x < -CLICK_DISTANCE ||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user