Merge m-c and birch

This commit is contained in:
Phil Ringnalda 2013-05-27 18:58:47 -07:00
commit f3918e9824
88 changed files with 1242 additions and 1544 deletions

View File

@ -663,15 +663,16 @@ function resizeWindowToChatAreaWidth(desired, cb) {
}
// Otherwise we request resize and expect a resize event
window.addEventListener("resize", function resize_handler() {
window.removeEventListener("resize", resize_handler);
// we did resize - but did we get far enough to be able to continue?
let newSize = window.SocialChatBar.chatbar.getBoundingClientRect().width;
let sizedOk = widthDeltaCloseEnough(newSize - desired);
if (!sizedOk) {
// not an error...
info("skipping this as we can't resize chat area to " + desired + " - got " + newSize);
return;
}
cb(sizedOk);
window.removeEventListener("resize", resize_handler);
executeSoon(function() {
cb(sizedOk);
});
});
window.resizeBy(delta, 0);
}

View File

@ -16,6 +16,7 @@ CPPSRCS := \
TESTSRCS := \
TestMustOverride.cpp \
TestNonHeapClass.cpp \
TestStackClass.cpp \
$(NULL)

View File

@ -11,6 +11,7 @@
#include "clang/Frontend/FrontendPluginRegistry.h"
#include "clang/Frontend/MultiplexConsumer.h"
#include "clang/Sema/Sema.h"
#include "llvm/ADT/DenseMap.h"
#define CLANG_VERSION_FULL (CLANG_VERSION_MAJOR * 100 + CLANG_VERSION_MINOR)
@ -32,9 +33,17 @@ private:
class StackClassChecker : public MatchFinder::MatchCallback {
public:
virtual void run(const MatchFinder::MatchResult &Result);
void noteInferred(QualType T, DiagnosticsEngine &Diag);
};
class NonHeapClassChecker : public MatchFinder::MatchCallback {
public:
virtual void run(const MatchFinder::MatchResult &Result);
void noteInferred(QualType T, DiagnosticsEngine &Diag);
};
StackClassChecker stackClassChecker;
NonHeapClassChecker nonheapClassChecker;
MatchFinder astMatcher;
};
@ -87,16 +96,6 @@ public:
if (hasCustomAnnotation(*M, "moz_must_override"))
must_overrides.push_back(*M);
}
// While we are looping over parent classes, we'll also check to make sure
// that the subclass has the annotation if the superclass does.
if (hasCustomAnnotation(parent, "moz_stack_class") &&
!hasCustomAnnotation(d, "moz_stack_class")) {
unsigned badInheritID = Diag.getDiagnosticIDs()->getCustomDiagID(
DiagnosticIDs::Error, "%0 inherits from a stack class %1");
Diag.Report(d->getLocation(), badInheritID)
<< d->getDeclName() << parent->getDeclName();
}
}
for (OverridesVector::iterator it = must_overrides.begin();
@ -123,6 +122,92 @@ public:
return true;
}
};
/**
* Where classes may be allocated. Regular classes can be allocated anywhere,
* non-heap classes on the stack or as static variables, and stack classes only
* on the stack. Note that stack classes subsumes non-heap classes.
*/
enum ClassAllocationNature {
RegularClass = 0,
NonHeapClass = 1,
StackClass = 2
};
/// A cached data of whether classes are stack classes, non-heap classes, or
/// neither.
DenseMap<const CXXRecordDecl *,
std::pair<const Decl *, ClassAllocationNature> > inferredAllocCauses;
ClassAllocationNature getClassAttrs(QualType T);
ClassAllocationNature getClassAttrs(CXXRecordDecl *D) {
// Normalize so that D points to the definition if it exists. If it doesn't,
// then we can't allocate it anyways.
if (!D->hasDefinition())
return RegularClass;
D = D->getDefinition();
// Base class: anyone with this annotation is obviously a stack class
if (MozChecker::hasCustomAnnotation(D, "moz_stack_class"))
return StackClass;
// See if we cached the result.
DenseMap<const CXXRecordDecl *,
std::pair<const Decl *, ClassAllocationNature> >::iterator it =
inferredAllocCauses.find(D);
if (it != inferredAllocCauses.end()) {
return it->second.second;
}
// Continue looking, we might be a stack class yet. Even if we're a nonheap
// class, it might be possible that we've inferred to be a stack class.
ClassAllocationNature type = RegularClass;
if (MozChecker::hasCustomAnnotation(D, "moz_nonheap_class")) {
type = NonHeapClass;
}
inferredAllocCauses.insert(std::make_pair(D,
std::make_pair((const Decl *)0, type)));
// Look through all base cases to figure out if the parent is a stack class or
// a non-heap class. Since we might later infer to also be a stack class, keep
// going.
for (CXXRecordDecl::base_class_iterator base = D->bases_begin(),
e = D->bases_end(); base != e; ++base) {
ClassAllocationNature super = getClassAttrs(base->getType());
if (super == StackClass) {
inferredAllocCauses[D] = std::make_pair(
base->getType()->getAsCXXRecordDecl(), StackClass);
return StackClass;
} else if (super == NonHeapClass) {
inferredAllocCauses[D] = std::make_pair(
base->getType()->getAsCXXRecordDecl(), NonHeapClass);
type = NonHeapClass;
}
}
// Maybe it has a member which is a stack class.
for (RecordDecl::field_iterator field = D->field_begin(), e = D->field_end();
field != e; ++field) {
ClassAllocationNature fieldType = getClassAttrs(field->getType());
if (fieldType == StackClass) {
inferredAllocCauses[D] = std::make_pair(*field, StackClass);
return StackClass;
} else if (fieldType == NonHeapClass) {
inferredAllocCauses[D] = std::make_pair(*field, NonHeapClass);
type = NonHeapClass;
}
}
return type;
}
ClassAllocationNature getClassAttrs(QualType T) {
while (const ArrayType *arrTy = T->getAsArrayTypeUnsafe())
T = arrTy->getElementType();
CXXRecordDecl *clazz = T->getAsCXXRecordDecl();
return clazz ? getClassAttrs(clazz) : RegularClass;
}
}
namespace clang {
@ -131,11 +216,13 @@ namespace ast_matchers {
/// This matcher will match any class with the stack class assertion or an
/// array of such classes.
AST_MATCHER(QualType, stackClassAggregate) {
QualType t = Node;
while (const ArrayType *arrTy = t->getAsArrayTypeUnsafe())
t = arrTy->getElementType();
CXXRecordDecl *clazz = t->getAsCXXRecordDecl();
return clazz && MozChecker::hasCustomAnnotation(clazz, "moz_stack_class");
return getClassAttrs(Node) == StackClass;
}
/// This matcher will match any class with the stack class assertion or an
/// array of such classes.
AST_MATCHER(QualType, nonheapClassAggregate) {
return getClassAttrs(Node) == NonHeapClass;
}
}
}
@ -151,10 +238,11 @@ DiagnosticsMatcher::DiagnosticsMatcher() {
astMatcher.addMatcher(newExpr(hasType(pointerType(
pointee(stackClassAggregate())
))).bind("node"), &stackClassChecker);
// Stack class assertion: a stack-class field is permitted only if it's a
// member of a class with the annotation
astMatcher.addMatcher(fieldDecl(hasType(stackClassAggregate())).bind("field"),
&stackClassChecker);
// Non-heap class assertion: new non-heap class is forbidden (unless placement
// new)
astMatcher.addMatcher(newExpr(hasType(pointerType(
pointee(nonheapClassAggregate())
))).bind("node"), &nonheapClassChecker);
}
void DiagnosticsMatcher::StackClassChecker::run(
@ -166,28 +254,90 @@ void DiagnosticsMatcher::StackClassChecker::run(
// Ignore the match if it's a local variable.
if (d->hasLocalStorage())
return;
Diag.Report(d->getLocation(), stackID) << d->getType();
noteInferred(d->getType(), Diag);
} else if (const CXXNewExpr *expr =
Result.Nodes.getNodeAs<CXXNewExpr>("node")) {
// If it's placement new, then this match doesn't count.
if (expr->getNumPlacementArgs() > 0)
return;
Diag.Report(expr->getStartLoc(), stackID) << expr->getAllocatedType();
} else if (const FieldDecl *field =
Result.Nodes.getNodeAs<FieldDecl>("field")) {
// AST matchers don't let me get the class that contains a field...
const RecordDecl *parent = field->getParent();
if (!MozChecker::hasCustomAnnotation(parent, "moz_stack_class")) {
// We use a more verbose error message here.
unsigned stackID = Diag.getDiagnosticIDs()->getCustomDiagID(
DiagnosticIDs::Error,
"member of type %0 in class %1 that is not a stack class");
Diag.Report(field->getLocation(), stackID) << field->getType() <<
parent->getDeclName();
}
noteInferred(expr->getAllocatedType(), Diag);
}
}
void DiagnosticsMatcher::StackClassChecker::noteInferred(QualType T,
DiagnosticsEngine &Diag) {
unsigned inheritsID = Diag.getDiagnosticIDs()->getCustomDiagID(
DiagnosticIDs::Note,
"%0 is a stack class because it inherits from a stack class %1");
unsigned memberID = Diag.getDiagnosticIDs()->getCustomDiagID(
DiagnosticIDs::Note,
"%0 is a stack class because member %1 is a stack class %2");
// Find the CXXRecordDecl that is the stack class of interest
while (const ArrayType *arrTy = T->getAsArrayTypeUnsafe())
T = arrTy->getElementType();
CXXRecordDecl *clazz = T->getAsCXXRecordDecl();
// Direct result, we're done.
if (MozChecker::hasCustomAnnotation(clazz, "moz_stack_class"))
return;
const Decl *cause = inferredAllocCauses[clazz].first;
if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(cause)) {
Diag.Report(clazz->getLocation(), inheritsID) << T << CRD->getDeclName();
} else if (const FieldDecl *FD = dyn_cast<FieldDecl>(cause)) {
Diag.Report(FD->getLocation(), memberID) << T << FD << FD->getType();
}
// Recursively follow this back.
noteInferred(cast<ValueDecl>(cause)->getType(), Diag);
}
void DiagnosticsMatcher::NonHeapClassChecker::run(
const MatchFinder::MatchResult &Result) {
DiagnosticsEngine &Diag = Result.Context->getDiagnostics();
unsigned stackID = Diag.getDiagnosticIDs()->getCustomDiagID(
DiagnosticIDs::Error, "variable of type %0 is not valid on the heap");
const CXXNewExpr *expr = Result.Nodes.getNodeAs<CXXNewExpr>("node");
// If it's placement new, then this match doesn't count.
if (expr->getNumPlacementArgs() > 0)
return;
Diag.Report(expr->getStartLoc(), stackID) << expr->getAllocatedType();
noteInferred(expr->getAllocatedType(), Diag);
}
void DiagnosticsMatcher::NonHeapClassChecker::noteInferred(QualType T,
DiagnosticsEngine &Diag) {
unsigned inheritsID = Diag.getDiagnosticIDs()->getCustomDiagID(
DiagnosticIDs::Note,
"%0 is a non-heap class because it inherits from a non-heap class %1");
unsigned memberID = Diag.getDiagnosticIDs()->getCustomDiagID(
DiagnosticIDs::Note,
"%0 is a non-heap class because member %1 is a non-heap class %2");
// Find the CXXRecordDecl that is the stack class of interest
while (const ArrayType *arrTy = T->getAsArrayTypeUnsafe())
T = arrTy->getElementType();
CXXRecordDecl *clazz = T->getAsCXXRecordDecl();
// Direct result, we're done.
if (MozChecker::hasCustomAnnotation(clazz, "moz_nonheap_class"))
return;
const Decl *cause = inferredAllocCauses[clazz].first;
if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(cause)) {
Diag.Report(clazz->getLocation(), inheritsID) << T << CRD->getDeclName();
} else if (const FieldDecl *FD = dyn_cast<FieldDecl>(cause)) {
Diag.Report(FD->getLocation(), memberID) << T << FD << FD->getType();
}
// Recursively follow this back.
noteInferred(cast<ValueDecl>(cause)->getType(), Diag);
}
class MozCheckAction : public PluginASTAction {
public:
ASTConsumer *CreateASTConsumer(CompilerInstance &CI, StringRef fileName) {

View File

@ -0,0 +1,62 @@
#define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class")))
#define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class")))
#include <stddef.h>
struct MOZ_NONHEAP_CLASS NonHeap {
int i;
void *operator new(size_t x) { return 0; }
void *operator new(size_t blah, char *buffer) { return buffer; }
};
template <class T>
struct MOZ_NONHEAP_CLASS TemplateClass {
T i;
};
void gobble(void *) { }
void misuseNonHeapClass(int len) {
NonHeap valid;
NonHeap alsoValid[2];
static NonHeap validStatic;
static NonHeap alsoValidStatic[2];
gobble(&valid);
gobble(&validStatic);
gobble(&alsoValid[0]);
gobble(new NonHeap); // expected-error {{variable of type 'NonHeap' is not valid on the heap}}
gobble(new NonHeap[10]); // expected-error {{variable of type 'NonHeap' is not valid on the heap}}
gobble(new TemplateClass<int>); // expected-error {{variable of type 'TemplateClass<int>' is not valid on the heap}}
gobble(len <= 5 ? &valid : new NonHeap); // expected-error {{variable of type 'NonHeap' is not valid on the heap}}
char buffer[sizeof(NonHeap)];
gobble(new (buffer) NonHeap);
}
NonHeap validStatic;
struct RandomClass {
NonHeap nonstaticMember; // expected-note {{'RandomClass' is a non-heap class because member 'nonstaticMember' is a non-heap class 'NonHeap'}}
static NonHeap staticMember;
};
struct MOZ_NONHEAP_CLASS RandomNonHeapClass {
NonHeap nonstaticMember;
static NonHeap staticMember;
};
struct BadInherit : NonHeap {}; // expected-note {{'BadInherit' is a non-heap class because it inherits from a non-heap class 'NonHeap'}}
struct MOZ_NONHEAP_CLASS GoodInherit : NonHeap {};
void useStuffWrongly() {
gobble(new BadInherit); // expected-error {{variable of type 'BadInherit' is not valid on the heap}}
gobble(new RandomClass); // expected-error {{variable of type 'RandomClass' is not valid on the heap}}
}
// Stack class overrides non-heap classes.
struct MOZ_STACK_CLASS StackClass {};
struct MOZ_NONHEAP_CLASS InferredStackClass : GoodInherit {
NonHeap nonstaticMember;
StackClass stackClass; // expected-note {{'InferredStackClass' is a stack class because member 'stackClass' is a stack class 'StackClass'}}
};
InferredStackClass global; // expected-error {{variable of type 'InferredStackClass' only valid on the stack}}

View File

@ -35,7 +35,7 @@ void misuseStackClass(int len) {
Stack notValid; // expected-error {{variable of type 'Stack' only valid on the stack}}
struct RandomClass {
Stack nonstaticMember; // expected-error {{member of type 'Stack' in class 'RandomClass' that is not a stack class}}
Stack nonstaticMember; // expected-note {{'RandomClass' is a stack class because member 'nonstaticMember' is a stack class 'Stack'}}
static Stack staticMember; // expected-error {{variable of type 'Stack' only valid on the stack}}
};
struct MOZ_STACK_CLASS RandomStackClass {
@ -43,5 +43,8 @@ struct MOZ_STACK_CLASS RandomStackClass {
static Stack staticMember; // expected-error {{variable of type 'Stack' only valid on the stack}}
};
struct BadInherit : Stack {}; // expected-error {{'BadInherit' inherits from a stack class 'Stack'}}
struct BadInherit : Stack {}; // expected-note {{'BadInherit' is a stack class because it inherits from a stack class 'Stack'}}
struct MOZ_STACK_CLASS GoodInherit : Stack {};
BadInherit moreInvalid; // expected-error {{variable of type 'BadInherit' only valid on the stack}}
RandomClass evenMoreInvalid; // expected-error {{variable of type 'RandomClass' only valid on the stack}}

View File

@ -9347,20 +9347,30 @@ if test -z "$MOZ_NATIVE_NSPR"; then
ac_configure_args="$ac_configure_args --with-arm-kuser"
fi
ac_configure_args="$ac_configure_args $NSPR_CONFIGURE_ARGS"
# Save these, so we can mess with them for the subconfigure ..
_SAVE_CFLAGS="$CFLAGS"
_SAVE_CPPFLAGS="$CPPFLAGS"
_SAVE_LDFLAGS="$LDFLAGS"
if test -n "$MOZ_LINKER" -a "$ac_cv_func_dladdr" = no ; then
# dladdr is supported by the new linker, even when the system linker doesn't
# support it. Trick nspr into using dladdr when it's not supported.
_SAVE_CPPFLAGS="$CPPFLAGS"
export CPPFLAGS="-include $_topsrcdir/mozglue/linker/dladdr.h $CPPFLAGS"
fi
_SAVE_LDFLAGS="$LDFLAGS"
export LDFLAGS="$LDFLAGS $NSPR_LDFLAGS"
export CFLAGS="$CFLAGS $MOZ_FRAMEPTR_FLAGS"
AC_OUTPUT_SUBDIRS(nsprpub)
# .. and restore them
unset CFLAGS
unset CPPFLAGS
unset LDFLAGS
CFLAGS="$_SAVE_CFLAGS"
CPPFLAGS="$_SAVE_CPPFLAGS"
LDFLAGS="$_SAVE_LDFLAGS"
if test -n "$MOZ_LINKER" -a "$ac_cv_func_dladdr" = no; then
unset CPPFLAGS
CPPFLAGS="$_SAVE_CFLAGS"
fi
ac_configure_args="$_SUBDIR_CONFIG_ARGS"
fi

View File

@ -30,3 +30,4 @@ DEPRECATED_OPERATION(PrefixedVisibilityAPI)
DEPRECATED_OPERATION(NodeIteratorDetach)
DEPRECATED_OPERATION(MozAudioData)
DEPRECATED_OPERATION(LenientThis)
DEPRECATED_OPERATION(GetPreventDefault)

View File

@ -1144,12 +1144,8 @@ NS_IMPL_RELEASE_INHERITED(nsContentSubtreeIterator, nsContentIterator)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsContentSubtreeIterator)
NS_INTERFACE_MAP_END_INHERITING(nsContentIterator)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsContentSubtreeIterator, nsContentIterator)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRange)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsContentSubtreeIterator, nsContentIterator)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRange)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(nsContentSubtreeIterator, nsContentIterator,
mRange)

View File

@ -1,3 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -8,17 +10,10 @@
using namespace mozilla;
using namespace mozilla::dom;
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMDeviceMotionEvent, nsDOMEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAcceleration)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAccelerationIncludingGravity)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRotationRate)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMDeviceMotionEvent, nsDOMEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAcceleration)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAccelerationIncludingGravity)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRotationRate)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_3(nsDOMDeviceMotionEvent, nsDOMEvent,
mAcceleration,
mAccelerationIncludingGravity,
mRotationRate)
NS_IMPL_ADDREF_INHERITED(nsDOMDeviceMotionEvent, nsDOMEvent)
NS_IMPL_RELEASE_INHERITED(nsDOMDeviceMotionEvent, nsDOMEvent)

View File

@ -1220,6 +1220,17 @@ const char* nsDOMEvent::GetEventName(uint32_t aEventType)
return nullptr;
}
bool
nsDOMEvent::GetPreventDefault() const
{
if (mOwner) {
if (nsIDocument* doc = mOwner->GetExtantDoc()) {
doc->WarnOnceAbout(nsIDocument::eGetPreventDefault);
}
}
return DefaultPrevented();
}
NS_IMETHODIMP
nsDOMEvent::GetPreventDefault(bool* aReturn)
{

View File

@ -189,10 +189,7 @@ public:
mozilla::dom::EventTarget* GetOriginalTarget() const;
mozilla::dom::EventTarget* GetExplicitOriginalTarget() const;
bool GetPreventDefault() const
{
return DefaultPrevented();
}
bool GetPreventDefault() const;
protected:

View File

@ -1,4 +1,5 @@
/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@ -94,17 +95,10 @@ nsDOMTouchEvent::~nsDOMTouchEvent()
}
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMTouchEvent, nsDOMUIEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTouches)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTargetTouches)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChangedTouches)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMTouchEvent, nsDOMUIEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTouches)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTargetTouches)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChangedTouches)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_3(nsDOMTouchEvent, nsDOMUIEvent,
mTouches,
mTargetTouches,
mChangedTouches)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMTouchEvent)
NS_INTERFACE_MAP_ENTRY(nsIDOMTouchEvent)

View File

@ -91,13 +91,8 @@ nsDOMUIEvent::Constructor(const mozilla::dom::GlobalObject& aGlobal,
return e.forget();
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMUIEvent, nsDOMEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mView)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMUIEvent, nsDOMEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mView)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(nsDOMUIEvent, nsDOMEvent,
mView)
NS_IMPL_ADDREF_INHERITED(nsDOMUIEvent, nsDOMEvent)
NS_IMPL_RELEASE_INHERITED(nsDOMUIEvent, nsDOMEvent)

View File

@ -25,15 +25,8 @@ nsDOMXULCommandEvent::nsDOMXULCommandEvent(mozilla::dom::EventTarget* aOwner,
NS_IMPL_ADDREF_INHERITED(nsDOMXULCommandEvent, nsDOMUIEvent)
NS_IMPL_RELEASE_INHERITED(nsDOMXULCommandEvent, nsDOMUIEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMXULCommandEvent,
nsDOMUIEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMXULCommandEvent,
nsDOMUIEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(nsDOMXULCommandEvent, nsDOMUIEvent,
mSourceEvent)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMXULCommandEvent)
NS_INTERFACE_MAP_ENTRY(nsIDOMXULCommandEvent)

View File

@ -75,14 +75,8 @@ HTMLButtonElement::~HTMLButtonElement()
// nsISupports
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLButtonElement,
nsGenericHTMLFormElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLButtonElement,
nsGenericHTMLFormElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(HTMLButtonElement, nsGenericHTMLFormElement,
mValidity)
NS_IMPL_ADDREF_INHERITED(HTMLButtonElement, Element)
NS_IMPL_RELEASE_INHERITED(HTMLButtonElement, Element)

View File

@ -21,15 +21,8 @@ HTMLDataListElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
return HTMLDataListElementBinding::Wrap(aCx, aScope, this);
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLDataListElement,
nsGenericHTMLElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOptions)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLDataListElement,
nsGenericHTMLElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOptions)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(HTMLDataListElement, nsGenericHTMLElement,
mOptions)
NS_IMPL_ADDREF_INHERITED(HTMLDataListElement, Element)
NS_IMPL_RELEASE_INHERITED(HTMLDataListElement, Element)

View File

@ -37,17 +37,8 @@ HTMLFieldSetElement::~HTMLFieldSetElement()
// nsISupports
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLFieldSetElement,
nsGenericHTMLFormElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mElements)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLFieldSetElement,
nsGenericHTMLFormElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElements)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_2(HTMLFieldSetElement, nsGenericHTMLFormElement,
mValidity, mElements)
NS_IMPL_ADDREF_INHERITED(HTMLFieldSetElement, Element)
NS_IMPL_RELEASE_INHERITED(HTMLFieldSetElement, Element)

View File

@ -76,18 +76,10 @@ HTMLTextAreaElement::HTMLTextAreaElement(already_AddRefed<nsINodeInfo> aNodeInfo
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLTextAreaElement,
nsGenericHTMLFormElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mControllers)
tmp->mState.Unlink();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLTextAreaElement,
nsGenericHTMLFormElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mControllers)
tmp->mState.Traverse(cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_3(HTMLTextAreaElement, nsGenericHTMLFormElement,
mValidity,
mControllers,
mState)
NS_IMPL_ADDREF_INHERITED(HTMLTextAreaElement, Element)
NS_IMPL_RELEASE_INHERITED(HTMLTextAreaElement, Element)

View File

@ -284,4 +284,19 @@ private:
bool mPlaceholderVisibility;
};
inline void
ImplCycleCollectionUnlink(nsTextEditorState& aField)
{
aField.Unlink();
}
inline void
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback,
nsTextEditorState& aField,
const char* aName,
uint32_t aFlags = 0)
{
aField.Traverse(aCallback);
}
#endif

View File

@ -138,13 +138,8 @@ ImageDocument::~ImageDocument()
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ImageDocument, MediaDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImageContent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ImageDocument, MediaDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mImageContent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(ImageDocument, MediaDocument,
mImageContent)
NS_IMPL_ADDREF_INHERITED(ImageDocument, MediaDocument)
NS_IMPL_RELEASE_INHERITED(ImageDocument, MediaDocument)

View File

@ -109,13 +109,8 @@ PluginDocument::~PluginDocument()
{}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PluginDocument, MediaDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPluginContent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PluginDocument, MediaDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPluginContent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(PluginDocument, MediaDocument,
mPluginContent)
NS_IMPL_ADDREF_INHERITED(PluginDocument, MediaDocument)
NS_IMPL_RELEASE_INHERITED(PluginDocument, MediaDocument)

View File

@ -202,33 +202,17 @@ nsHTMLDocument::nsHTMLDocument()
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLDocument, nsDocument)
NS_ASSERTION(!nsCCUncollectableMarker::InGeneration(cb, tmp->GetMarkedCCGeneration()),
"Shouldn't traverse nsHTMLDocument!");
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImages)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mApplets)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEmbeds)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLinks)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAnchors)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mScripts)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mForms)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFormControls)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWyciwygChannel)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMidasCommandManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLDocument, nsDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mImages)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mApplets)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mEmbeds)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLinks)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mAnchors)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mScripts)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mForms)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFormControls)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWyciwygChannel)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMidasCommandManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_10(nsHTMLDocument, nsDocument,
mImages,
mApplets,
mEmbeds,
mLinks,
mAnchors,
mScripts,
mForms,
mFormControls,
mWyciwygChannel,
mMidasCommandManager)
NS_IMPL_ADDREF_INHERITED(nsHTMLDocument, nsDocument)
NS_IMPL_RELEASE_INHERITED(nsHTMLDocument, nsDocument)

View File

@ -40,13 +40,8 @@ nsDOMTimeEvent::nsDOMTimeEvent(mozilla::dom::EventTarget* aOwner,
}
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMTimeEvent, nsDOMEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mView)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMTimeEvent, nsDOMEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mView)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(nsDOMTimeEvent, nsDOMEvent,
mView)
NS_IMPL_ADDREF_INHERITED(nsDOMTimeEvent, nsDOMEvent)
NS_IMPL_RELEASE_INHERITED(nsDOMTimeEvent, nsDOMEvent)

View File

@ -51,15 +51,8 @@ SVGSVGElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
return SVGSVGElementBinding::Wrap(aCx, aScope, this);
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DOMSVGTranslatePoint,
nsISVGPoint)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DOMSVGTranslatePoint,
nsISVGPoint)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(DOMSVGTranslatePoint, nsISVGPoint,
mElement)
NS_IMPL_ADDREF_INHERITED(DOMSVGTranslatePoint, nsISVGPoint)
NS_IMPL_RELEASE_INHERITED(DOMSVGTranslatePoint, nsISVGPoint)

View File

@ -26,14 +26,8 @@ SVGSwitchElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aScope)
//----------------------------------------------------------------------
// nsISupports methods
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SVGSwitchElement,
SVGSwitchElementBase)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mActiveChild)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGSwitchElement,
SVGSwitchElementBase)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mActiveChild)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(SVGSwitchElement, SVGSwitchElementBase,
mActiveChild)
NS_IMPL_ADDREF_INHERITED(SVGSwitchElement,SVGSwitchElementBase)
NS_IMPL_RELEASE_INHERITED(SVGSwitchElement,SVGSwitchElementBase)

View File

@ -324,17 +324,11 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(XULDocument, XMLDocument)
// document, so we'll traverse the table here instead of from the element.
if (tmp->mTemplateBuilderTable)
tmp->mTemplateBuilderTable->EnumerateRead(TraverseTemplateBuilders, &cb);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCurrentPrototype)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMasterPrototype)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCommandDispatcher)
uint32_t i, count = tmp->mPrototypes.Length();
for (i = 0; i < count; ++i) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mPrototypes[i]");
cb.NoteXPCOMChild(static_cast<nsIScriptGlobalObjectOwner*>(tmp->mPrototypes[i]));
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrototypes);
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLocalStore)
if (tmp->mOverlayLoadObservers.IsInitialized())

View File

@ -273,19 +273,11 @@ NS_NewXULTreeBuilder(nsISupports* aOuter, REFNSIID aIID, void** aResult)
NS_IMPL_ADDREF_INHERITED(nsXULTreeBuilder, nsXULTemplateBuilder)
NS_IMPL_RELEASE_INHERITED(nsXULTreeBuilder, nsXULTemplateBuilder)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXULTreeBuilder, nsXULTemplateBuilder)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBoxObject)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSelection)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPersistStateStore)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mObservers)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULTreeBuilder, nsXULTemplateBuilder)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBoxObject)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSelection)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPersistStateStore)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObservers)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_4(nsXULTreeBuilder, nsXULTemplateBuilder,
mBoxObject,
mSelection,
mPersistStateStore,
mObservers)
DOMCI_DATA(XULTreeBuilder, nsXULTreeBuilder)

View File

@ -11,15 +11,8 @@
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DOMCursor,
DOMRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallback)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DOMCursor,
DOMRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallback)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(DOMCursor, DOMRequest,
mCallback)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(DOMCursor)
NS_INTERFACE_MAP_ENTRY(nsIDOMDOMCursor)

View File

@ -39,6 +39,7 @@ function runTest() {
iframe.sendTouchEvent("touchstart", [1], [10], [10], [2], [2],
[20], [0.5], 1, 0);
} else {
iframe.removeEventListener('mozbrowserlocationchange', onlocchange);
SimpleTest.finish();
}
break;
@ -55,6 +56,7 @@ function runTest() {
ok(true, "Receive a touchend event.");
iframe.sendTouchEvent("touchcancel", [1], [10], [10], [2], [2],
[20], [0.5], 1, 0);
iframe.removeEventListener('mozbrowserlocationchange', onlocchange);
SimpleTest.finish();
break;
}

View File

@ -304,12 +304,14 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
// nsDOMEventTargetHelper does it for us.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSource)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTransaction)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mError)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)
tmp->mResultVal = JSVAL_VOID;
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSource)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mTransaction)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mError)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(IDBRequest, IDBWrapperCache)

View File

@ -2332,15 +2332,8 @@ TabChildGlobal::Init()
MM_CHILD);
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TabChildGlobal,
nsDOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TabChildGlobal,
nsDOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(TabChildGlobal, nsDOMEventTargetHelper,
mMessageManager)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChildGlobal)
NS_INTERFACE_MAP_ENTRY(nsIMessageListenerManager)

View File

@ -130,3 +130,5 @@ MozAudioDataWarning=The Mozilla Audio Data API is deprecated. Please use the We
LenientThisWarning=Ignoring get or set of property that has [LenientThis] because the "this" object is incorrect.
# LOCALIZATION NOTE: Do not translate "nsIDOMWindowUtils", "getWindowWithOuterId", or "nsIWindowMediator"
GetWindowWithOuterIdWarning=Use of nsIDOMWindowUtils.getOuterWindowWithId() is deprecated. Instead, use the nsIWindowMediator method of the same name.
# LOCALIZATION NOTE: Do not translate "getPreventDefault" or "defaultPrevented".
GetPreventDefaultWarning=Use of getPreventDefault() is deprecated. Use defaultPrevented instead.

View File

@ -160,9 +160,10 @@ TelephonyCall::NotifyError(const nsAString& aError)
}
}
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(TelephonyCall,
NS_IMPL_CYCLE_COLLECTION_INHERITED_2(TelephonyCall,
nsDOMEventTargetHelper,
mTelephony)
mTelephony,
mError);
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TelephonyCall)
NS_INTERFACE_MAP_ENTRY(nsIDOMTelephonyCall)

View File

@ -18,13 +18,8 @@ ChangeAttributeTxn::ChangeAttributeTxn()
{
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ChangeAttributeTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ChangeAttributeTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(ChangeAttributeTxn, EditTxn,
mElement)
NS_IMPL_ADDREF_INHERITED(ChangeAttributeTxn, EditTxn)
NS_IMPL_RELEASE_INHERITED(ChangeAttributeTxn, EditTxn)

View File

@ -25,15 +25,8 @@ class nsIEditor;
#define kNullCh (PRUnichar('\0'))
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ChangeCSSInlineStyleTxn,
EditTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ChangeCSSInlineStyleTxn,
EditTxn)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(ChangeCSSInlineStyleTxn, EditTxn,
mElement)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ChangeCSSInlineStyleTxn)
NS_INTERFACE_MAP_END_INHERITING(EditTxn)

View File

@ -34,17 +34,10 @@ CreateElementTxn::CreateElementTxn()
{
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CreateElementTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNewNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRefNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CreateElementTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNewNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRefNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_3(CreateElementTxn, EditTxn,
mParent,
mNewNode,
mRefNode)
NS_IMPL_ADDREF_INHERITED(CreateElementTxn, EditTxn)
NS_IMPL_RELEASE_INHERITED(CreateElementTxn, EditTxn)

View File

@ -17,17 +17,10 @@ DeleteNodeTxn::DeleteNodeTxn()
{
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DeleteNodeTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRefNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DeleteNodeTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRefNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_3(DeleteNodeTxn, EditTxn,
mNode,
mParent,
mRefNode)
NS_IMPL_ADDREF_INHERITED(DeleteNodeTxn, EditTxn)
NS_IMPL_RELEASE_INHERITED(DeleteNodeTxn, EditTxn)

View File

@ -32,15 +32,8 @@ DeleteRangeTxn::DeleteRangeTxn()
{
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DeleteRangeTxn,
EditAggregateTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRange)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DeleteRangeTxn,
EditAggregateTxn)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRange)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(DeleteRangeTxn, EditAggregateTxn,
mRange)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeleteRangeTxn)
NS_INTERFACE_MAP_END_INHERITING(EditAggregateTxn)

View File

@ -28,13 +28,8 @@ DeleteTextTxn::DeleteTextTxn() :
{
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DeleteTextTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCharData)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DeleteTextTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCharData)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(DeleteTextTxn, EditTxn,
mCharData)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeleteTextTxn)
NS_INTERFACE_MAP_END_INHERITING(EditTxn)

View File

@ -16,16 +16,8 @@ EditAggregateTxn::EditAggregateTxn()
{
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(EditAggregateTxn, EditTxn)
tmp->mChildren.Clear();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(EditAggregateTxn, EditTxn)
for (uint32_t i = 0; i < tmp->mChildren.Length(); ++i) {
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mChildren[i]");
cb.NoteXPCOMChild(static_cast<nsITransaction*>(tmp->mChildren[i]));
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(EditAggregateTxn, EditTxn,
mChildren)
NS_IMPL_ADDREF_INHERITED(EditAggregateTxn, EditTxn)
NS_IMPL_RELEASE_INHERITED(EditAggregateTxn, EditTxn)

View File

@ -31,15 +31,9 @@ IMETextTxn::IMETextTxn()
{
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IMETextTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mElement)
// mRangeList can't lead to cycles
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IMETextTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
// mRangeList can't lead to cycles
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(IMETextTxn, EditTxn,
mElement)
// mRangeList can't lead to cycles
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IMETextTxn)
if (aIID.Equals(IMETextTxn::GetCID())) {

View File

@ -29,15 +29,9 @@ InsertElementTxn::InsertElementTxn()
{
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(InsertElementTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(InsertElementTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_2(InsertElementTxn, EditTxn,
mNode,
mParent)
NS_IMPL_ADDREF_INHERITED(InsertElementTxn, EditTxn)
NS_IMPL_RELEASE_INHERITED(InsertElementTxn, EditTxn)

View File

@ -24,13 +24,8 @@ InsertTextTxn::InsertTextTxn()
{
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(InsertTextTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mElement)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(InsertTextTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(InsertTextTxn, EditTxn,
mElement)
NS_IMPL_ADDREF_INHERITED(InsertTextTxn, EditTxn)
NS_IMPL_RELEASE_INHERITED(InsertTextTxn, EditTxn)

View File

@ -26,17 +26,10 @@ JoinElementTxn::JoinElementTxn()
{
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(JoinElementTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mLeftNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRightNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(JoinElementTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLeftNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRightNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_3(JoinElementTxn, EditTxn,
mLeftNode,
mRightNode,
mParent)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(JoinElementTxn)
NS_INTERFACE_MAP_END_INHERITING(EditTxn)

View File

@ -29,15 +29,9 @@ SplitElementTxn::SplitElementTxn()
{
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SplitElementTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNewLeftNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SplitElementTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNewLeftNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_2(SplitElementTxn, EditTxn,
mParent,
mNewLeftNode)
NS_IMPL_ADDREF_INHERITED(SplitElementTxn, EditTxn)
NS_IMPL_RELEASE_INHERITED(SplitElementTxn, EditTxn)

View File

@ -51,13 +51,8 @@ AddStyleSheetTxn::AddStyleSheetTxn()
{
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(AddStyleSheetTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSheet)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(AddStyleSheetTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSheet)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(AddStyleSheetTxn, EditTxn,
mSheet)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AddStyleSheetTxn)
NS_INTERFACE_MAP_END_INHERITING(EditTxn)
@ -69,7 +64,7 @@ AddStyleSheetTxn::Init(nsIEditor *aEditor, nsCSSStyleSheet *aSheet)
mEditor = aEditor;
mSheet = aSheet;
return NS_OK;
}
@ -78,7 +73,7 @@ NS_IMETHODIMP
AddStyleSheetTxn::DoTransaction()
{
NS_ENSURE_TRUE(mEditor && mSheet, NS_ERROR_NOT_INITIALIZED);
AddStyleSheet(mEditor, mSheet);
return NS_OK;
}
@ -87,7 +82,7 @@ NS_IMETHODIMP
AddStyleSheetTxn::UndoTransaction()
{
NS_ENSURE_TRUE(mEditor && mSheet, NS_ERROR_NOT_INITIALIZED);
RemoveStyleSheet(mEditor, mSheet);
return NS_OK;
}
@ -106,13 +101,8 @@ RemoveStyleSheetTxn::RemoveStyleSheetTxn()
{
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(RemoveStyleSheetTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mSheet)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(RemoveStyleSheetTxn, EditTxn)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSheet)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(RemoveStyleSheetTxn, EditTxn,
mSheet)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RemoveStyleSheetTxn)
NS_INTERFACE_MAP_END_INHERITING(EditTxn)

View File

@ -241,7 +241,7 @@ class Heap : public js::HeapBase<T>
* specialization, define a HandleBase<T> specialization containing them.
*/
template <typename T>
class MOZ_STACK_CLASS Handle : public js::HandleBase<T>
class MOZ_NONHEAP_CLASS Handle : public js::HandleBase<T>
{
friend class MutableHandle<T>;

View File

@ -31,6 +31,6 @@ ifdef ENABLE_CLANG_PLUGIN
# Load the clang plugin from the mozilla topsrcdir. This implies that the clang
# plugin is only usable if we're building js/src under mozilla/, though.
CLANG_PLUGIN := $(DEPTH)/../../build/clang-plugin/$(DLL_PREFIX)clang-plugin$(DLL_SUFFIX)
OS_CXXFLAGS += -fplugin=$(CLANG_PLUGIN)
OS_CFLAGS += -fplugin=$(CLANG_PLUGIN)
OS_CXXFLAGS += -Xclang -load -Xclang $(CLANG_PLUGIN) -Xclang -add-plugin -Xclang moz-check
OS_CFLAGS += -Xclang -load -Xclang $(CLANG_PLUGIN) -Xclang -add-plugin -Xclang moz-check
endif

View File

@ -2468,12 +2468,6 @@ BEGIN_CASE(JSOP_REST)
if (!rest)
goto error;
PUSH_COPY(ObjectValue(*rest));
if (!SetInitializerObjectType(cx, script, regs.pc, rest, GenericObject))
goto error;
rootType0 = GetTypeCallerInitObject(cx, JSProto_Array);
if (!rootType0)
goto error;
rest->setType(rootType0);
}
END_CASE(JSOP_REST)

View File

@ -121,15 +121,6 @@ StackFrame::initVarsToUndefined()
SetValueRangeToUndefined(slots(), script()->nfixed);
}
inline JSObject *
StackFrame::createRestParameter(JSContext *cx)
{
JS_ASSERT(fun()->hasRest());
unsigned nformal = fun()->nargs - 1, nactual = numActualArgs();
unsigned nrest = (nactual > nformal) ? nactual - nformal : 0;
return NewDenseCopiedArray(cx, nrest, argv() + nformal, NULL);
}
inline Value &
StackFrame::unaliasedVar(unsigned i, MaybeCheckAliasing checkAliasing)
{

View File

@ -226,6 +226,29 @@ StackFrame::copyRawFrameSlots(AutoValueVector *vec)
return true;
}
JSObject *
StackFrame::createRestParameter(JSContext *cx)
{
JS_ASSERT(fun()->hasRest());
unsigned nformal = fun()->nargs - 1, nactual = numActualArgs();
unsigned nrest = (nactual > nformal) ? nactual - nformal : 0;
Value *restvp = argv() + nformal;
RootedObject obj(cx, NewDenseCopiedArray(cx, nrest, restvp, NULL));
if (!obj)
return NULL;
RootedTypeObject type(cx, types::GetTypeCallerInitObject(cx, JSProto_Array));
if (!type)
return NULL;
obj->setType(type);
/* Ensure that values in the rest array are represented in the type of the array. */
for (unsigned i = 0; i < nrest; i++)
types::AddTypePropertyId(cx, obj, JSID_VOID, restvp[i]);
return obj;
}
static inline void
AssertDynamicScopeMatchesStaticScope(JSContext *cx, JSScript *script, JSObject *scope)
{

View File

@ -544,7 +544,7 @@ class StackFrame
ArgumentsObject &argsObj() const;
void initArgsObj(ArgumentsObject &argsobj);
inline JSObject *createRestParameter(JSContext *cx);
JSObject *createRestParameter(JSContext *cx);
/*
* Scope chain

View File

@ -382,16 +382,26 @@
* MOZ_STACK_CLASS: Applies to all classes. Any class with this annotation is
* expected to live on the stack, so it is a compile-time error to use it, or
* an array of such objects, as a global or static variable, or as the type of
* a new expression (unless placement new is being used). It may be a base or
* a member of another class only if both classes are marked with this
* annotation.
* a new expression (unless placement new is being used). If a member of
* another class uses this class, or if another class inherits from this
* class, then it is considered to be a stack class as well, although this
* attribute need not be provided in such cases.
* MOZ_NONHEAP_CLASS: Applies to all classes. Any class with this annotation is
* expected to live on the stack or in static storage, so it is a compile-time
* error to use it, or an array of such objects, as the type of a new
* expression (unless placement new is being used). If a member of another
* class uses this class, or if another class inherits from this class, then
* it is considered to be a stack class as well, although this attribute need
* not be provided in such cases.
*/
#ifdef MOZ_CLANG_PLUGIN
# define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override")))
# define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class")))
# define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class")))
#else
# define MOZ_MUST_OVERRIDE /* nothing */
# define MOZ_STACK_CLASS /* nothing */
# define MOZ_NONHEAP_CLASS /* nothing */
#endif /* MOZ_CLANG_PLUGIN */
#endif /* __cplusplus */

View File

@ -5,17 +5,19 @@
<!DOCTYPE window [
]>
<window id="winTest" title="Title Test" windowtype="Test Type"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<dialog id="dia"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<dialog id="dia"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<vbox id="things">
<checkbox id="testBox" label="box" />
<textbox id="textInput" size="6" value="test" label="input" />
<textbox id="textInput2" size="6" value="test" label="input" />
<textbox id="textInput3" class="asdf" size="6" value="test" label="input" />
</vbox>
<iframe id="iframe" name="iframename" src="chrome://marionette/content/test2.xul"/>
<iframe id="iframe" name="iframename" src="chrome://marionette/content/test_nested_iframe.xul"/>
</dialog>
<vbox id="things">
<checkbox id="testBox" label="box" />
<textbox id="textInput" size="6" value="test" label="input" />
<textbox id="textInput2" size="6" value="test" label="input" />
<textbox id="textInput3" class="asdf" size="6" value="test" label="input" />
</vbox>
<iframe id="iframe" name="iframename" src="chrome://marionette/content/test2.xul"/>
<iframe id="iframe" name="iframename" src="chrome://marionette/content/test_nested_iframe.xul"/>
</dialog>
</window>

View File

@ -479,10 +479,6 @@ class Marionette(object):
response = self._send_message('setSearchTimeout', 'ok', value=timeout)
return response
def send_mouse_event(self, send):
response = self._send_message('sendMouseEvent', 'ok', value=send)
return response
@property
def current_window_handle(self):
self.window = self._send_message('getWindow', 'value')
@ -529,6 +525,10 @@ class Marionette(object):
response = self._send_message('getUrl', 'value')
return response
def get_window_type(self):
response = self._send_message('getWindowType', 'value')
return response
def navigate(self, url):
response = self._send_message('goUrl', 'ok', value=url)
return response

View File

@ -159,6 +159,15 @@ class MarionetteTestCase(CommonTestCase):
qemu = self.marionette.extra_emulators[self.extra_emulator_index]
return qemu
def wait_for_condition(self, method, timeout=30):
timeout = float(timeout) + time.time()
while time.time() < timeout:
value = method(self.marionette)
if value:
return value
time.sleep(0.5)
else:
raise TimeoutException("wait_for_condition timed out")
class MarionetteJSTestCase(CommonTestCase):

View File

@ -31,11 +31,10 @@ class MarionetteTouchMixin(object):
self.execute_script("%s.tap(arguments[0], null, null, null, null, arguments[1]);" % self.library_name, [element, send_all])
def double_tap(self, element):
self.check_element(element)
self.execute_script("%s.dbltap(arguments[0]);" % self.library_name, [element])
action = Actions(self)
action.double_tap(element).perform()
def flick(self, element, x1, y1, x2, y2, duration=200):
self.check_element(element)
action = Actions(self)
action.flick(element, x1, y1, x2, y2, duration).perform()

View File

@ -0,0 +1,102 @@
from marionette import Actions
def press_release(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
action = Actions(marionette)
button = marionette.find_element("id", "button1")
action.press(button).release().perform()
wait_for_condition(lambda m: expected in m.execute_script("return document.getElementById('button1').innerHTML;"))
def move_element(marionette, wait_for_condition, expected1, expected2):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
ele = marionette.find_element("id", "button1")
drop = marionette.find_element("id", "button2")
action = Actions(marionette)
action.press(ele).move(drop).release()
action.perform()
wait_for_condition(lambda m: expected1 in m.execute_script("return document.getElementById('button1').innerHTML;"))
wait_for_condition(lambda m: expected2 in m.execute_script("return document.getElementById('button2').innerHTML;"))
def move_element_offset(marionette, wait_for_condition, expected1, expected2):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
ele = marionette.find_element("id", "button1")
action = Actions(marionette)
action.press(ele).move_by_offset(0,150).move_by_offset(0, 150).release()
action.perform()
wait_for_condition(lambda m: expected1 in m.execute_script("return document.getElementById('button1').innerHTML;"))
wait_for_condition(lambda m: expected2 in m.execute_script("return document.getElementById('button2').innerHTML;"))
def chain(marionette, wait_for_condition, expected1, expected2):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
marionette.set_search_timeout(15000)
action = Actions(marionette)
button1 = marionette.find_element("id", "button1")
action.press(button1).perform()
button2 = marionette.find_element("id", "delayed")
wait_for_condition(lambda m: expected1 in m.execute_script("return document.getElementById('button1').innerHTML;"))
action.move(button2).release().perform()
wait_for_condition(lambda m: expected2 in m.execute_script("return document.getElementById('delayed').innerHTML;"))
def chain_flick(marionette, wait_for_condition, expected1, expected2):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element("id", "button1")
action = Actions(marionette)
action.flick(button, 0, 0, 0, 200).perform()
wait_for_condition(lambda m: expected1 in m.execute_script("return document.getElementById('button1').innerHTML;"))
wait_for_condition(lambda m: expected2 in m.execute_script("return document.getElementById('buttonFlick').innerHTML;"))
def wait(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
action = Actions(marionette)
button = marionette.find_element("id", "button1")
action.press(button).wait().release().perform()
wait_for_condition(lambda m: expected in m.execute_script("return document.getElementById('button1').innerHTML;"))
def wait_with_value(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element("id", "button1")
action = Actions(marionette)
action.press(button).wait(0.01).release()
action.perform()
wait_for_condition(lambda m: expected in m.execute_script("return document.getElementById('button1').innerHTML;"))
def context_menu(marionette, wait_for_condition, expected1, expected2):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element("id", "button1")
action = Actions(marionette)
action.press(button).wait(5).perform()
wait_for_condition(lambda m: expected1 in m.execute_script("return document.getElementById('button1').innerHTML;"))
action.release().perform()
wait_for_condition(lambda m: expected2 in m.execute_script("return document.getElementById('button1').innerHTML;"))
def long_press_action(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element("id", "button1")
action = Actions(marionette)
action.long_press(button, 5).perform()
wait_for_condition(lambda m: expected in m.execute_script("return document.getElementById('button1').innerHTML;"))
def single_tap(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element("id", "button1")
action = Actions(marionette)
action.tap(button).perform()
wait_for_condition(lambda m: expected in m.execute_script("return document.getElementById('button1').innerHTML;"))
def double_tap(marionette, wait_for_condition, expected):
testAction = marionette.absolute_url("testAction.html")
marionette.navigate(testAction)
button = marionette.find_element("id", "button1")
action = Actions(marionette)
action.double_tap(button).perform()
wait_for_condition(lambda m: expected in m.execute_script("return document.getElementById('button1').innerHTML;"))

View File

@ -0,0 +1,32 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from marionette_test import MarionetteTestCase
from errors import MarionetteException
class testElementTouch(MarionetteTestCase):
def test_touch(self):
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
button = self.marionette.find_element("id", "button1")
button.tap()
expected = "button1-touchstart-touchend-mousemove-mousedown-mouseup-click"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
button.tap(0, 300)
expected = "button2-touchstart-touchend-mousemove-mousedown-mouseup-click"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button2').innerHTML;") == expected)
def test_invisible(self):
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
ele = self.marionette.find_element("id", "hidden")
self.assertRaises(MarionetteException, ele.tap)
def test_scrolling(self):
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
ele = self.marionette.find_element("id", "buttonScroll")
ele.tap()
expected = "buttonScroll-touchstart-touchend-mousemove-mousedown-mouseup-click"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('buttonScroll').innerHTML;") == expected)

View File

@ -2,22 +2,35 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import time
from marionette_test import MarionetteTestCase
from gestures import smooth_scroll, pinch
class testGestures(MarionetteTestCase):
check_in_viewport = """
function elementInViewport(el) {
let rect = el.getBoundingClientRect();
return (rect.top >= window.pageYOffset &&
rect.left >= window.pageXOffset &&
rect.bottom <= (window.pageYOffset + window.innerHeight) &&
rect.right <= (window.pageXOffset + window.innerWidth)
);
};
"""
def test_smooth_scroll(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkScrollStart")
smooth_scroll(self.marionette, button, "y", -1, 250)
time.sleep(15)
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkScroll').innerHTML;"))
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
button = self.marionette.find_element("id", "button2")
self.assertFalse(self.marionette.execute_script("%s; return elementInViewport(document.getElementById('buttonScroll'));" % self.check_in_viewport))
smooth_scroll(self.marionette, button, "y", -1, 800)
buttonScroll = self.marionette.find_element("id", "buttonScroll")
self.wait_for_condition(lambda m: m.execute_script("%s; return elementInViewport(arguments[0]);" % self.check_in_viewport, [buttonScroll]) == True)
self.assertEqual("button2-touchstart", self.marionette.execute_script("return document.getElementById('button2').innerHTML;"))
"""
#This test doesn't manipulate the page, filed Bug 870377 about it.
def test_pinch(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkScrollStart")
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
button = self.marionette.find_element("id", "button1")
pinch(self.marionette, button, 0, 0, 0, 0, 0, -50, 0, 50)
time.sleep(15)
"""

View File

@ -2,7 +2,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import time
from marionette_test import MarionetteTestCase
from marionette import Marionette
from marionette_touch import MarionetteTouchMixin
@ -13,28 +12,45 @@ class TestTouchMixin(MarionetteTestCase):
super(TestTouchMixin, self).setUp()
self.marionette.__class__ = type('Marionette', (Marionette, MarionetteTouchMixin), {})
self.marionette.setup_touch()
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
def tap(self):
button = self.marionette.find_element("id", "button1")
self.marionette.tap(button)
def double_tap(self):
button = self.marionette.find_element("id", "button1")
self.marionette.double_tap(button)
def test_tap(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkCopy")
self.marionette.tap(button)
time.sleep(10)
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkCopy').innerHTML;"))
self.tap()
expected = "button1-touchstart-touchend-mousedown-mouseup-click"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
def test_dbtap(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozMouse")
self.marionette.double_tap(button)
time.sleep(10)
self.assertEqual("TouchEnd2", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_tap_mouse_shim(self):
self.marionette.execute_script("window.wrappedJSObject.MouseEventShim = 'mock value';")
self.tap()
expected = "button1-touchstart-touchend"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
def test_double_tap(self):
self.double_tap()
expected = "button1-touchstart-touchend-mousemove-mousedown-mouseup-click-touchstart-touchend-mousemove-mousedown-mouseup-click"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
"""
#Enable this when we have logic in double_tap to handle the shim
def test_double_tap_mouse_shim(self):
self.marionette.execute_script("window.wrappedJSObject.MouseEventShim = 'mock value';")
self.double_tap()
expected = "button1-touchstart-touchend-touchstart-touchend"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
"""
def test_flick(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkScrollStart")
self.marionette.flick(button, 0, 0, 0, -250)
time.sleep(15)
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkScroll').innerHTML;"))
self.assertEqual("Start", self.marionette.execute_script("return document.getElementById('mozLinkScrollStart').innerHTML;"))
button = self.marionette.find_element("id", "button1")
self.marionette.flick(button, 0, 0, 0, 200)
expected = "button1-touchstart-touchmove"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
self.assertEqual("buttonFlick-touchmove-touchend", self.marionette.execute_script("return document.getElementById('buttonFlick').innerHTML;"))

View File

@ -2,61 +2,64 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import time
from marionette_test import MarionetteTestCase
from marionette import MultiActions, Actions
class testSingleFinger(MarionetteTestCase):
class testMultiFinger(MarionetteTestCase):
def test_move_element(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
start = self.marionette.find_element("id", "mozLink")
drop = self.marionette.find_element("id", "mozLinkPos")
ele = self.marionette.find_element("id", "mozLinkCopy")
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
start = self.marionette.find_element("id", "button1")
drop = self.marionette.find_element("id", "button2")
ele = self.marionette.find_element("id", "button3")
multi_action = MultiActions(self.marionette)
action1 = Actions(self.marionette)
action2 = Actions(self.marionette)
action1.press(start).move(drop).wait(3).release()
action2.press(ele).wait().release()
multi_action.add(action1).add(action2).perform()
time.sleep(15)
self.assertEqual("Move", self.marionette.execute_script("return document.getElementById('mozLink').innerHTML;"))
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkPos').innerHTML;"))
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkCopy').innerHTML;"))
expected = "button1-touchstart"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
self.assertEqual("button2-touchmove-touchend", self.marionette.execute_script("return document.getElementById('button2').innerHTML;"))
self.assertIn("button3-touchstart-touchend", self.marionette.execute_script("return document.getElementById('button3').innerHTML;"))
def test_move_offset_element(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
start = self.marionette.find_element("id", "mozLink")
ele = self.marionette.find_element("id", "mozLinkCopy")
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
start = self.marionette.find_element("id", "button1")
ele = self.marionette.find_element("id", "button3")
multi_action = MultiActions(self.marionette)
action1 = Actions(self.marionette)
action2 = Actions(self.marionette)
action1.press(start).move_by_offset(0,300).wait().release()
action2.press(ele).wait(5).release()
multi_action.add(action1).add(action2).perform()
time.sleep(15)
self.assertEqual("Move", self.marionette.execute_script("return document.getElementById('mozLink').innerHTML;"))
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkPos').innerHTML;"))
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkCopy').innerHTML;"))
expected = "button1-touchstart"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
self.assertEqual("button2-touchmove-touchend", self.marionette.execute_script("return document.getElementById('button2').innerHTML;"))
self.assertIn("button3-touchstart-touchend", self.marionette.execute_script("return document.getElementById('button3').innerHTML;"))
def test_three_fingers(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
start_one = self.marionette.find_element("id", "mozLink")
start_two = self.marionette.find_element("id", "mozLinkStart")
drop_two = self.marionette.find_element("id", "mozLinkEnd")
ele = self.marionette.find_element("id", "mozLinkCopy2")
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
start_one = self.marionette.find_element("id", "button1")
start_two = self.marionette.find_element("id", "button2")
element1 = self.marionette.find_element("id", "button3")
element2 = self.marionette.find_element("id", "button4")
multi_action = MultiActions(self.marionette)
action1 = Actions(self.marionette)
action2 = Actions(self.marionette)
action3 = Actions(self.marionette)
action1.press(start_one).move_by_offset(0,300).release()
action2.press(ele).wait().wait(5).release()
action3.press(start_two).move(drop_two).wait(2).release()
action2.press(element1).wait().wait(5).release()
action3.press(element2).wait().wait().release()
multi_action.add(action1).add(action2).add(action3).perform()
time.sleep(15)
self.assertEqual("Move", self.marionette.execute_script("return document.getElementById('mozLink').innerHTML;"))
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkPos').innerHTML;"))
self.assertTrue(self.marionette.execute_script("return document.getElementById('mozLinkCopy2').innerHTML >= 5000;"))
self.assertTrue(self.marionette.execute_script("return document.getElementById('mozLinkEnd').innerHTML >= 5000;"))
expected = "button1-touchstart"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
self.assertEqual("button2-touchmove-touchend", self.marionette.execute_script("return document.getElementById('button2').innerHTML;"))
button3_text = self.marionette.execute_script("return document.getElementById('button3').innerHTML;")
button4_text = self.marionette.execute_script("return document.getElementById('button4').innerHTML;")
self.assertIn("button3-touchstart-touchend", button3_text)
self.assertIn("button4-touchstart-touchend", button4_text)
self.assertTrue(int(button3_text.rsplit("-")[-1]) >= 5000)
self.assertTrue(int(button4_text.rsplit("-")[-1]) >= 5000)

View File

@ -2,210 +2,83 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import time
from marionette_test import MarionetteTestCase
from marionette import Actions
from errors import NoSuchElementException, MarionetteException
from errors import MarionetteException
#add this directory to the path
import os
import sys
sys.path.append(os.path.dirname(__file__))
from single_finger_functions import *
class testSingleFinger(MarionetteTestCase):
def test_wait(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkCopy")
action = Actions(self.marionette)
action.press(button).wait(0.2).release()
action.perform()
time.sleep(15)
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkCopy').innerHTML;"))
def test_press_release(self):
press_release(self.marionette, self.wait_for_condition, "button1-touchstart-touchend-mousemove-mousedown-mouseup-click")
def test_move_element(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
ele = self.marionette.find_element("id", "mozLink")
drop = self.marionette.find_element("id", "mozLinkPos")
action = Actions(self.marionette)
action.press(ele).move(drop).release()
action.perform()
time.sleep(15)
self.assertEqual("Move", self.marionette.execute_script("return document.getElementById('mozLink').innerHTML;"))
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkPos').innerHTML;"))
move_element(self.marionette, self.wait_for_condition, "button1-touchstart", "button2-touchmove-touchend")
"""
#Skipping due to Bug 874914
def test_move_by_offset(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
ele = self.marionette.find_element("id", "mozLink")
action = Actions(self.marionette)
action.press(ele).move_by_offset(0,150).move_by_offset(0,150).release()
action.perform()
time.sleep(15)
self.assertEqual("Move", self.marionette.execute_script("return document.getElementById('mozLink').innerHTML;"))
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkPos').innerHTML;"))
def test_chain(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
action = Actions(self.marionette)
button1 = self.marionette.find_element("id", "mozLinkCopy2")
action.press(button1).perform()
button2 = self.marionette.find_element("id", "delayed")
time.sleep(5)
action.move(button2).release().perform()
time.sleep(15)
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('delayed').innerHTML;"))
move_element_offset(self.marionette, self.wait_for_condition, "button1-touchstart", "button2-touchmove-touchend")
"""
def test_no_press(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
action = Actions(self.marionette)
action.release()
self.assertRaises(NoSuchElementException, action.perform)
self.assertRaises(MarionetteException, action.perform)
def test_mouse_wait(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(True)
action = Actions(self.marionette)
button = self.marionette.find_element("id", "mozMouse")
action.press(button).wait().release().perform()
time.sleep(15)
self.assertEqual("MouseClick", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_wait(self):
wait(self.marionette, self.wait_for_condition, "button1-touchstart-touchend-mousemove-mousedown-mouseup-click")
def test_mouse_wait_more(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(True)
action = Actions(self.marionette)
button = self.marionette.find_element("id", "mozMouse")
action.press(button).wait(0.1).release().perform()
time.sleep(15)
self.assertEqual("MouseClick", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_wait_with_value(self):
wait_with_value(self.marionette, self.wait_for_condition, "button1-touchstart-touchend-mousemove-mousedown-mouseup-click")
def test_mouse_no_wait(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(True)
action = Actions(self.marionette)
button = self.marionette.find_element("id", "mozMouse")
action.press(button).release().perform()
time.sleep(15)
self.assertEqual("MouseClick", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_no_mouse_wait(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(False)
action = Actions(self.marionette)
button = self.marionette.find_element("id", "mozMouse")
action.press(button).wait().release().perform()
time.sleep(15)
self.assertEqual("TouchEnd", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_no_mouse_no_wait(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(False)
action = Actions(self.marionette)
button = self.marionette.find_element("id", "mozMouse")
action.press(button).release().perform()
time.sleep(15)
self.assertEqual("TouchEnd", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_long_press(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkCopy")
action = Actions(self.marionette)
action.press(button).wait(5).perform()
time.sleep(10)
self.assertEqual("Context", self.marionette.execute_script("return document.getElementById('mozLinkCopy').innerHTML;"))
action.release().perform()
time.sleep(10)
self.assertEqual("ContextEnd", self.marionette.execute_script("return document.getElementById('mozLinkCopy').innerHTML;"))
def test_context_menu(self):
context_menu(self.marionette, self.wait_for_condition, "button1-touchstart-contextmenu", "button1-touchstart-contextmenu-touchend")
def test_long_press_action(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkCopy")
action = Actions(self.marionette)
action.long_press(button, 5).perform()
time.sleep(10)
self.assertEqual("ContextEnd", self.marionette.execute_script("return document.getElementById('mozLinkCopy').innerHTML;"))
long_press_action(self.marionette, self.wait_for_condition, "button1-touchstart-contextmenu-touchend")
"""
#Skipping due to Bug 865334
def test_long_press_fail(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkCopy")
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
button = self.marionette.find_element("id", "button1Copy")
action = Actions(self.marionette)
action.press(button).long_press(button, 5)
self.assertRaises(MarionetteException, action.perform)
"""
def test_wrong_value(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.assertRaises(MarionetteException, self.marionette.send_mouse_event, "boolean")
def test_chain(self):
chain(self.marionette, self.wait_for_condition, "button1-touchstart", "delayed-touchmove-touchend")
"""
#Skipping due to Bug 874914. Flick uses chained moveByOffset calls
def test_chain_flick(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkScrollStart")
action = Actions(self.marionette)
action.flick(button, 0, 0, 0, -250).perform()
time.sleep(15)
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkScroll').innerHTML;"))
self.assertEqual("Start", self.marionette.execute_script("return document.getElementById('mozLinkScrollStart').innerHTML;"))
chain_flick(self.marionette, self.wait_for_condition, "button1-touchstart-touchmove", "buttonFlick-touchmove-touchend")
"""
"""
#Skipping due to Bug 865334
def test_touchcancel_chain(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLinkCancel")
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
button = self.marionette.find_element("id", "button1")
action = Actions(self.marionette)
action.press(button).wait(5).cancel()
action.perform()
time.sleep(15)
self.assertEqual("End", self.marionette.execute_script("return document.getElementById('mozLinkCancel').innerHTML;"))
expected = "button1-touchstart-touchcancel"
self.wait_for_condition(lambda m: m.execute_script("return document.getElementById('button1').innerHTML;") == expected)
"""
def test_mouse_single_tap(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(True)
button = self.marionette.find_element("id", "mozMouse")
action = Actions(self.marionette)
action.tap(button).perform()
time.sleep(15)
self.assertEqual("MouseClick", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_single_tap(self):
single_tap(self.marionette, self.wait_for_condition, "button1-touchstart-touchend-mousemove-mousedown-mouseup-click")
def test_mouse_double_tap(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(True)
button = self.marionette.find_element("id", "mozMouse")
action = Actions(self.marionette)
action.double_tap(button).perform()
time.sleep(15)
self.assertEqual("MouseClick2", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_double_tap(self):
double_tap(self.marionette, self.wait_for_condition, "button1-touchstart-touchend-mousemove-mousedown-mouseup-click-touchstart-touchend-mousemove-mousedown-mouseup-click")
def test_touch(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(False)
button = self.marionette.find_element("id", "mozMouse")
action = Actions(self.marionette)
action.tap(button).perform()
time.sleep(10)
self.assertEqual("TouchEnd", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_dbtouch(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(False)
button = self.marionette.find_element("id", "mozMouse")
action = Actions(self.marionette)
action.double_tap(button).perform()
time.sleep(10)
self.assertEqual("TouchEnd2", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))

View File

@ -0,0 +1,98 @@
from marionette_test import MarionetteTestCase
from marionette import Actions
from errors import MarionetteException
#add this directory to the path
import os
import sys
sys.path.append(os.path.dirname(__file__))
from single_finger_functions import *
class testSingleFingerMouse(MarionetteTestCase):
def setUp(self):
super(MarionetteTestCase, self).setUp()
# set context menu related preferences needed for some tests
self.marionette.set_context("chrome")
self.enabled = self.marionette.execute_script("""
let prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
let value = false;
try {
value = prefs.getBoolPref("ui.click_hold_context_menus");
}
catch (e) {}
prefs.setBoolPref("ui.click_hold_context_menus", true);
return value;
""")
self.wait_time = self.marionette.execute_script("""
let prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
let value = 750;
try {
value = prefs.getIntPref("ui.click_hold_context_menus.delay");
}
catch (e) {}
prefs.setIntPref("ui.click_hold_context_menus.delay", value);
return value;
""")
self.marionette.set_context("content")
def tearDown(self):
self.marionette.set_context("chrome")
self.marionette.execute_script(
"""
let prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
prefs.setBoolPref("ui.click_hold_context_menus", arguments[0]);
""", [self.enabled])
self.marionette.execute_script(
"""
let prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
prefs.setIntPref("ui.click_hold_context_menus.delay", arguments[0]);
""", [self.wait_time])
self.marionette.set_context("content")
super(MarionetteTestCase, self).tearDown()
def test_press_release(self):
press_release(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click")
def test_move_element(self):
move_element(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown", "button2-mousemove-mouseup")
def test_move_by_offset(self):
move_element_offset(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown", "button2-mousemove-mouseup")
def test_wait(self):
wait(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click")
def test_wait_with_value(self):
wait_with_value(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click")
def test_context_menu(self):
context_menu(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-contextmenu", "button1-mousemove-mousedown-contextmenu-mouseup-click")
def test_long_press_action(self):
long_press_action(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-contextmenu-mouseup-click")
"""
//Skipping due to Bug 865334
def test_long_press_fail(self):
testAction = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testAction)
button = self.marionette.find_element("id", "button1Copy")
action = Actions(self.marionette)
action.press(button).long_press(button, 5)
assertRaises(MarionetteException, action.perform)
"""
def test_chain(self):
chain(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown", "delayed-mousemove-mouseup")
def test_chain_flick(self):
chain_flick(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mousemove", "buttonFlick-mousemove-mouseup")
def test_single_tap(self):
single_tap(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click")
def test_double_tap(self):
double_tap(self.marionette, self.wait_for_condition, "button1-mousemove-mousedown-mouseup-click-mousemove-mousedown-mouseup-click")

View File

@ -1,26 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import time
from marionette_test import MarionetteTestCase
from marionette import HTMLElement
class testSingleFinger(MarionetteTestCase):
def test_mouse_single_tap(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(True)
button = self.marionette.find_element("id", "mozMouse")
button.tap()
time.sleep(15)
self.assertEqual("MouseClick", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))
def test_touch(self):
testTouch = self.marionette.absolute_url("testAction.html")
self.marionette.navigate(testTouch)
self.marionette.send_mouse_event(False)
button = self.marionette.find_element("id", "mozMouse")
button.tap()
time.sleep(10)
self.assertEqual("TouchEnd", self.marionette.execute_script("return document.getElementById('mozMouse').innerHTML;"))

View File

@ -1,35 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import time
from marionette_test import MarionetteTestCase
from marionette import HTMLElement
from errors import MarionetteException
class testTouch(MarionetteTestCase):
def test_touch(self):
testTouch = self.marionette.absolute_url("testTouch.html")
self.marionette.navigate(testTouch)
button = self.marionette.find_element("id", "mozLink")
button.tap(0, 300)
time.sleep(10)
self.assertEqual("Clicked", self.marionette.execute_script("return document.getElementById('mozLinkPos').innerHTML;"))
button.tap()
time.sleep(10)
self.assertEqual("Clicked", self.marionette.execute_script("return document.getElementById('mozLink').innerHTML;"))
def test_invisible(self):
testTouch = self.marionette.absolute_url("testTouch.html")
self.marionette.navigate(testTouch)
ele = self.marionette.find_element("id", "testh2")
self.assertRaises(MarionetteException, ele.tap)
def test_scrolling(self):
testTouch = self.marionette.absolute_url("testTouch.html")
self.marionette.navigate(testTouch)
ele = self.marionette.find_element("id", "scroll")
ele.tap()
time.sleep(10)
self.assertEqual("Clicked", self.marionette.execute_script("return document.getElementById('scroll').innerHTML;"))

View File

@ -0,0 +1,33 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from marionette_test import MarionetteTestCase
#TODO use @skip_if_b2g when Bug 875921 is fixed
class TestTitleChrome(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.set_context("chrome")
self.win = self.marionette.current_window_handle
self.marionette.execute_script("window.open('chrome://marionette/content/test.xul', 'foo', 'chrome,centerscreen');")
self.marionette.switch_to_window('foo')
self.assertNotEqual(self.win, self.marionette.current_window_handle)
def tearDown(self):
self.assertNotEqual(self.win, self.marionette.current_window_handle)
self.marionette.execute_script("window.close();")
self.marionette.switch_to_window(self.win)
MarionetteTestCase.tearDown(self)
def test_get_chrome_title(self):
title = self.marionette.execute_script("return window.document.documentElement.getAttribute('title');")
self.assertEqual(title, self.marionette.title)
self.assertEqual('Title Test', self.marionette.title)
class TestTitle(MarionetteTestCase):
def test_get_html_title(self):
test_html = self.marionette.absolute_url("test.html")
self.marionette.navigate(test_html)
self.assertEqual('Marionette Test', self.marionette.title)

View File

@ -0,0 +1,26 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from marionette_test import MarionetteTestCase
class TestWindowTypeChrome(MarionetteTestCase):
def setUp(self):
MarionetteTestCase.setUp(self)
self.marionette.set_context("chrome")
self.win = self.marionette.current_window_handle
self.marionette.execute_script("window.open('chrome://marionette/content/test.xul', 'foo', 'chrome,centerscreen');")
self.marionette.switch_to_window('foo')
self.assertNotEqual(self.win, self.marionette.current_window_handle)
def tearDown(self):
self.assertNotEqual(self.win, self.marionette.current_window_handle)
self.marionette.execute_script("window.close();")
self.marionette.switch_to_window(self.win)
MarionetteTestCase.tearDown(self)
def test_get_window_type(self):
window_type = self.marionette.execute_script("return window.document.documentElement.getAttribute('windowtype');")
self.assertEqual(window_type, self.marionette.get_window_type())
self.assertEqual('Test Type', self.marionette.get_window_type())

View File

@ -11,9 +11,6 @@ b2g = true
; true if the test should be skipped
skip = false
; true if the test requires unagi
unagi = false
[test_getstatus.py]
[test_import_script.py]
[test_import_script_content.py.py]
@ -46,14 +43,13 @@ b2g = false
[test_timeouts.py]
b2g = false
[test_touch.py]
[test_element_touch.py]
b2g = true
browser = false
[test_gesture.py]
b2g = true
browser = false
unagi = true
[test_marionette_touch.py]
b2g = true
@ -62,15 +58,13 @@ browser = false
[test_single_finger.py]
b2g = true
browser = false
[test_single_finger_desktop.py]
b2g = false
[test_multi_finger.py]
b2g = true
browser = false
[test_tap.py]
b2g = true
browser = false
[test_simpletest_pass.js]
[test_simpletest_sanity.py]
[test_simpletest_chrome.js]
@ -86,3 +80,7 @@ b2g = false
[test_screenshot.py]
[test_cookies.py]
b2g = false
[test_window_title.py]
b2g = false
[test_window_type.py]
b2g = false

View File

@ -5,259 +5,90 @@
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<head>
<title>Marionette Test</title>
</head>
<body>
<h1 id="testh1">Test Page</h1>
<!-- "mozLink" and "mozLinkPos" work together to perform touchdown on mozLink, vertical move and then touchup on mozLinkPos-->
<button id="mozLink" style="position:absolute;left:0px;top:55px;" type="button" allowevents=true>Button1</button>
<button id="mozLinkPos" style="position:absolute;left:0px;top:355px;" type="button" allowevents=true>Button2</button>
<!-- "mozLinkCopy" listens for a touchdown and touchup -->
<button id="mozLinkCopy" style="position:absolute;left:0px;top:455px;" type="button" allowevents=true>Button3</button>
<!-- "mozLinkScroll" listens for scroll -->
<button id="mozLinkScroll" style="position:absolute;left:0px;top:655px;" type="button" allowevents=true>Button8</button>
<!-- "mozLinkScrollStart" listens for scroll -->
<button id="mozLinkScrollStart" style="position:absolute;left:0px;top:405px;" type="button" allowevents=true>Button9</button>
<!-- "mozLinkStart" and "mozLinkEnd" work together to perform touchdown on mozLinkStart, horizontal move and then touchup on mozLinkEnd -->
<button id="mozLinkStart" style="position:absolute;left:10px;top:200px;" type="button" allowevents=true>Press</button>
<button id="mozLinkEnd" style="position:absolute;left:140px;top:200px;" type="button" allowevents=true>Release</button>
<!-- "mozLinkCopy2" listens for a touchdown and touchup. It shows the time when it's fired-->
<button id="mozLinkCopy2" style="position:absolute;left:80px;top:455px;" type="button" allowevents=true>Button4</button>
<!-- "mozLinkCancel" listens for a touchdown and touchcancel -->
<button id="mozLinkCancel" style="position:absolute;left:0px;top:255px;" type="button" allowevents=true>Button5</button>
<!-- "mozMouse" listens for mouse events -->
<button id="mozMouse" style="position:absolute;left:0px;top:305px;" type="button" allowevents=true>Button7</button>
<button id="button1" style="position:absolute;left:0px;top:55px;" type="button" allowevents=true>button1</button>
<button id="button2" style="position:absolute;left:0px;top:355px;" type="button" allowevents=true>button2</button>
<button id="button3" style="position:absolute;left:0px;top:455px;" type="button" allowevents=true>button3</button>
<button id="button4" style="position:absolute;left:100px;top:455px;" type="button" allowevents=true>button4</button>
<button id="buttonScroll" style="position:absolute;left:100px;top:855px;" type="button" allowevents=true>buttonScroll</button>
<h2 id="hidden" style="visibility: hidden" class="linkClass">Hidden</h2>
<button id="buttonFlick" style="position:absolute;left:0px;top:255px;" type="button" allowevents=true>buttonFlick</button>
<script type="text/javascript">
window.ready = true;
var press = document.getElementById("mozLink");
var second = document.getElementById("mozLinkCopy");
var third = document.getElementById("mozLinkStart");
var fourth = document.getElementById("mozLinkCopy2");
var fifth = document.getElementById("mozLinkCancel");
var sixth = document.getElementById("mozMouse");
var seventh = document.getElementById("mozLinkScrollStart");
// touchmove and touchend must be performed on the same element as touchstart
// here is press for vertical move
press.addEventListener("touchstart", function(){changePressText("mozLink")}, false);
press.addEventListener("touchmove", changeMoveText, false);
press.addEventListener("touchend", changeReleaseText, false);
// here is second for a tap
second.addEventListener("touchstart", function(){changePressText("mozLinkCopy")}, false);
second.addEventListener("touchend", function(){changeClickText("mozLinkCopy")}, false);
// change for contextmenu
second.addEventListener("contextmenu", onContextMenuChange, false);
// here is third for horizontal move
third.addEventListener("touchstart", function(){changePressText("mozLinkStart")}, false);
third.addEventListener("touchmove", changeHorizontalMove, false);
third.addEventListener("touchend", changeHorizontalRelease, false);
// here is fourth for touch up and down with time shown
fourth.addEventListener("touchstart", changeTimePress, false);
fourth.addEventListener("touchend", changeTimeRelease, false);
// here is fifth for a cancel
fifth.addEventListener("touchstart", function(){changePressText("mozLinkCancel")}, false);
fifth.addEventListener("touchcancel", function(){changeClickText("mozLinkCancel")}, false);
// here is sixth for mouse event
sixth.addEventListener("touchstart", function(){changeMouseText("TouchStart")}, false);
sixth.addEventListener("touchend", function(){changeMouseText("TouchEnd")}, false);
sixth.addEventListener("mousemove", function(){changeMouseText("MouseMove")}, false);
sixth.addEventListener("mousedown", function(){changeMouseText("MouseDown")}, false);
sixth.addEventListener("mouseup", function(){changeMouseText("MouseUp")}, false);
sixth.addEventListener("click", function(){changeMouseText("MouseClick")}, false);
// here is seventh for a scroll
seventh.addEventListener("touchstart", function(){changePressText("mozLinkScrollStart")}, false);
seventh.addEventListener("touchend", function(){changeScrollText("mozLinkScroll")}, false);
function changeMouseText(strId) {
var mouse = document.getElementById("mozMouse");
switch(strId) {
case "TouchStart":
if (mouse.innerHTML == "MouseClick") {
mouse.innerHTML = "TouchStart2";
}
else if (mouse.innerHTML == "TouchEnd") {
mouse.innerHTML = "TouchStart2";
}
else {
mouse.innerHTML = strId;
}
break;
case "TouchEnd":
if (mouse.innerHTML == "TouchStart") {
mouse.innerHTML = strId;
}
else if (mouse.innerHTML == "TouchStart2") {
mouse.innerHTML = "TouchEnd2";
}
else {
mouse.innerHTML = "Error";
}
break;
case "MouseMove":
if (mouse.innerHTML == "TouchEnd") {
mouse.innerHTML = strId;
}
else if (mouse.innerHTML == "TouchEnd2") {
mouse.innerHTML = "MouseMove2";
}
else {
mouse.innerHTML = "Error";
}
break;
case "MouseDown":
if (mouse.innerHTML == "MouseMove") {
mouse.innerHTML = strId;
}
else if (mouse.innerHTML == "MouseMove2") {
mouse.innerHTML = "MouseDown2";
}
else {
mouse.innerHTML = "Error";
}
break;
case "MouseUp":
if (mouse.innerHTML == "MouseDown") {
mouse.innerHTML = strId;
}
else if (mouse.innerHTML == "MouseDown2") {
mouse.innerHTML = "MouseUp2";
}
else {
mouse.innerHTML = "Error";
}
break;
case "MouseClick":
if (mouse.innerHTML == "MouseUp") {
mouse.innerHTML = strId;
}
else if (mouse.innerHTML == "MouseUp2") {
mouse.innerHTML = "MouseClick2";
}
else {
mouse.innerHTML = "Error";
}
break;
default:
mouse.innerHTML = "Error";
break;
}
var button3Timer = null;
var button4Timer = null;
//appends passed in text to the innerHTML of the event's target
function appendText(text) {
return function(evt) {
var element;
if (evt.type.indexOf("touch") !== -1) {
if (evt.type == "touchstart") {
element = evt.target;
}
else {
//since the target of touchstart is the target of all subsequent events, then
//changedTouches holds the current coordinates of this touch event, so we
//use these coordinates to find the element under the touch event
var touches = evt.changedTouches;
var x = touches[0].clientX;
var y = touches[0].clientY;
element = document.elementFromPoint(x,y);
}
}
//handle mouse events or contextmenu
else {
element = evt.target;
}
element.innerHTML += text;
};
};
//use this function outside of attachListeners when you want to test sendMouseOnlyEvents on a target
function attachMouseListeners(element) {
element.addEventListener("contextmenu", appendText("-contextmenu"), false);
element.addEventListener("mousedown", appendText("-mousedown"), false);
element.addEventListener("mousemove", appendText("-mousemove"), false);
element.addEventListener("mouseup", appendText("-mouseup"), false);
element.addEventListener("click", appendText("-click"), false);
};
function attachListeners(id) {
var element = document.getElementById(id);
element.addEventListener("touchstart", appendText("-touchstart"), false);
element.addEventListener("touchmove", appendText("-touchmove"), false);
element.addEventListener("touchend", appendText("-touchend"), false);
element.addEventListener("touchcancel", appendText("-touchcancel"), false);
attachMouseListeners(element);
};
//for tracking time on an element
function addTimers(id, timer) {
var element = document.getElementById(id);
element.addEventListener("touchstart", function(evt) { timer = (new Date()).getTime();}, false);
element.addEventListener("touchend", function(evt) { timer = (new Date()).getTime() - timer; evt.target.innerHTML += "-" + timer;}, false);
}
function changePressText(strId) {
var press = document.getElementById(strId);
press.innerHTML = "Start";
}
function changeMoveText() {
var move = document.getElementById("mozLink");
move.innerHTML = "Move";
}
function checkPosition(event, ele) {
var touches = event.changedTouches;
var clientX = touches[0].clientX;
var clientY = touches[0].clientY;
var release = document.getElementById(ele);
var boxr = release.getBoundingClientRect();
return (clientY >= boxr.top &&
clientY <= boxr.bottom &&
clientX >= boxr.left &&
clientX <= boxr.right);
}
function changeReleaseText(event) {
if (checkPosition(event, "mozLinkPos")) {
document.getElementById("mozLinkPos").innerHTML = "End";
}
}
function changeHorizontalMove() {
var press = document.getElementById("mozLinkStart");
if (press.innerHTML == "Start") {
var d = new Date();
press.innerHTML = d.getTime();
}
}
function changeHorizontalRelease(event) {
if (checkPosition(event, "mozLinkEnd")) {
var press = document.getElementById("mozLinkStart");
var d = new Date();
var timeDiff = d.getTime() - press.innerHTML;
document.getElementById("mozLinkEnd").innerHTML = timeDiff;
}
}
function changeClickText(strId) {
var second = document.getElementById(strId);
if (second.innerHTML == "Start") {
second.innerHTML = "End";
}
else if (second.innerHTML == "Context") {
second.innerHTML = "ContextEnd";
}
else {
second.innerHTML = "Error";
}
}
function changeScrollText(strId) {
var seventh = document.getElementById(strId);
if (elementInViewport(seventh)) {
seventh.innerHTML = "End";
}
else {
seventh.innerHTML = "Error";
}
}
function changeTimePress() {
var fourth = document.getElementById("mozLinkCopy2");
var d = new Date();
fourth.innerHTML = d.getTime();
attachListeners("button1");
attachListeners("button2");
attachListeners("button3");
attachListeners("button4");
attachListeners("buttonScroll");
addTimers("button3");
addTimers("button4");
var buttonFlick = document.getElementById("buttonFlick");
attachMouseListeners(buttonFlick);
function createDelayed() {
var newButton = document.createElement("button");
newButton.id = "delayed";
newButton.setAttribute("style", "position:absolute;left:220px;top:455px;");
var content = document.createTextNode("Button6");
var content = document.createTextNode("delayed");
newButton.appendChild(content);
document.body.appendChild(newButton);
}
function changeTimeRelease(event) {
var fourth = document.getElementById("mozLinkCopy2");
if (fourth.innerHTML != "Button4") {
var d = new Date();
var timeDiff = d.getTime() - fourth.innerHTML;
fourth.innerHTML = timeDiff;
}
else {
fourth.innerHTML = "Error";
}
if (checkPosition(event, "delayed")) {
document.getElementById("delayed").innerHTML = "End";
}
}
function onContextMenuChange() {
var context = document.getElementById("mozLinkCopy");
context.innerHTML = "Context";
}
function elementInViewport(el) {
var top = el.offsetTop;
var left = el.offsetLeft;
var width = el.offsetWidth;
var height = el.offsetHeight;
while(el.offsetParent) {
el = el.offsetParent;
top += el.offsetTop;
left += el.offsetLeft;
}
return (top >= window.pageYOffset &&
left >= window.pageXOffset &&
(top + height) <= (window.pageYOffset + window.innerHeight) &&
(left + width) <= (window.pageXOffset + window.innerWidth));
}
newButton.addEventListener("mousemove", appendText("-mousemove"), false);
newButton.addEventListener("mouseup", appendText("-mouseup"), false);
newButton.addEventListener("click", appendText("-click"), false);
};
window.setTimeout(createDelayed, 5000);
</script>
</body>
</html>

View File

@ -1,51 +0,0 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE html>
<html>
<head>
<script type="application/javascript" src="shim.js">
</script>
<title>Marionette Test</title>
</head>
<body>
<h1 id="testh1">Test Page</h1>
<script type="text/javascript">
window.ready = true;
setTimeout(addDelayedElement, 1000);
function addDelayedElement() {
var newDiv = document.createElement("div");
newDiv.id = "newDiv";
var newContent = document.createTextNode("I am a newly created div!");
newDiv.appendChild(newContent);
document.body.appendChild(newDiv);
}
function clicked() {
var link = document.getElementById("mozLink");
link.innerHTML = "Clicked";
}
function clicked2() {
var link2 = document.getElementById("scroll");
link2.innerHTML = "Clicked";
}
function clicked3() {
var link3 = document.getElementById("mozLinkPos");
link3.innerHTML = "Clicked";
}
</script>
<button id="mozLink" style="position:absolute;left:0px;top:55px;" type="button" onclick="clicked()" allowevents=true>Click Me!</button>
<button id="mozLinkPos" style="position:absolute;left:0px;top:355px;" type="button" onclick="clicked3()" allowevents=true>Position!</button>
<div id="testDiv">
<a href="#" id="divLink" class="linkClass" onclick="clicked()">Div click me!</a>
<a href="#" id="divLink2" class="linkClass" onclick="clicked()">Div click me!</a>
</div>
<input name="myInput" type="text" value="asdf"/>
<input name="myCheckBox" type="checkbox" />
<h2 id="testh2" style="visibility: hidden" class="linkClass">Hidden</h2>
<h3 id="testh3">Voluntary Termination</h3>
<br style="margin-bottom:600px;"/>
<button id="scroll" type="button" onclick="clicked2()" allowevents=true>Click Me!</button>
</body>
</html>

View File

@ -1,7 +1,7 @@
import os
from setuptools import setup, find_packages
version = '0.5.27'
version = '0.5.28'
# get documentation from the README
try:

View File

@ -1075,7 +1075,24 @@ MarionetteDriverActor.prototype = {
*/
getTitle: function MDA_getTitle() {
this.command_id = this.getCommandId();
this.sendAsync("getTitle", {}, this.command_id);
if (this.context == "chrome"){
var curWindow = this.getCurrentWindow();
var title = curWindow.document.documentElement.getAttribute('title');
this.sendResponse(title, this.command_id);
}
else {
this.sendAsync("getTitle", {}, this.command_id);
}
},
/**
* Gets the current type of the window
*/
getWindowType: function MDA_getWindowType() {
this.command_id = this.getCommandId();
var curWindow = this.getCurrentWindow();
var type = curWindow.document.documentElement.getAttribute('windowtype');
this.sendResponse(type, this.command_id);
},
/**
@ -1302,23 +1319,6 @@ MarionetteDriverActor.prototype = {
}
},
/**
* Set a value to decide if sending mouse event
*
* @param object aRequest
* 'value' holds the boolean value
*/
sendMouseEvent: function MDA_sendMouseEvent(aRequest) {
this.command_id = this.getCommandId();
if (this.context == "chrome") {
this.sendError("Not in Chrome", 500, null, this.command_id);
}
else {
this.sendAsync("sendMouseEvent", {value: aRequest.value,
command_id: this.command_id});
}
},
/**
* Set timeout for page loading, searching and scripts
*
@ -1362,7 +1362,7 @@ MarionetteDriverActor.prototype = {
let x = aRequest.x;
let y = aRequest.y;
if (this.context == "chrome") {
this.sendError("Not in Chrome", 500, null, this.command_id);
this.sendError("Command 'singleTap' is not available in chrome context", 500, null, this.command_id);
}
else {
this.sendAsync("singleTap",
@ -1384,7 +1384,7 @@ MarionetteDriverActor.prototype = {
actionChain: function MDA_actionChain(aRequest) {
this.command_id = this.getCommandId();
if (this.context == "chrome") {
this.sendError("Not in Chrome", 500, null, this.command_id);
this.sendError("Command 'actionChain' is not available in chrome context", 500, null, this.command_id);
}
else {
this.sendAsync("actionChain",
@ -1408,7 +1408,7 @@ MarionetteDriverActor.prototype = {
multiAction: function MDA_multiAction(aRequest) {
this.command_id = this.getCommandId();
if (this.context == "chrome") {
this.sendError("Not in Chrome", 500, null, this.command_id);
this.sendError("Command 'multiAction' is not available in chrome context", 500, null, this.command_id);
}
else {
this.sendAsync("multiAction",
@ -2203,7 +2203,6 @@ MarionetteDriverActor.prototype.requestTypes = {
"executeAsyncScript": MarionetteDriverActor.prototype.executeWithCallback,
"executeJSScript": MarionetteDriverActor.prototype.executeJSScript,
"setSearchTimeout": MarionetteDriverActor.prototype.setSearchTimeout,
"sendMouseEvent": MarionetteDriverActor.prototype.sendMouseEvent,
"findElement": MarionetteDriverActor.prototype.findElement,
"findElements": MarionetteDriverActor.prototype.findElements,
"clickElement": MarionetteDriverActor.prototype.clickElement,
@ -2219,6 +2218,7 @@ MarionetteDriverActor.prototype.requestTypes = {
"getElementPosition": MarionetteDriverActor.prototype.getElementPosition,
"clearElement": MarionetteDriverActor.prototype.clearElement,
"getTitle": MarionetteDriverActor.prototype.getTitle,
"getWindowType": MarionetteDriverActor.prototype.getWindowType,
"getPageSource": MarionetteDriverActor.prototype.getPageSource,
"goUrl": MarionetteDriverActor.prototype.goUrl,
"getUrl": MarionetteDriverActor.prototype.getUrl,

View File

@ -57,19 +57,16 @@ let originalOnError;
let checkTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
// Send move events about this often
let EVENT_INTERVAL = 30; // milliseconds
// The current array of all pending touches
let touches = [];
// For assigning unique ids to all touches
let nextTouchId = 1000;
//Keep track of active Touches
let touchIds = {};
// last touch for each fingerId
let multiLast = {};
// last touch for single finger
let lastTouch = null;
// last touch type
let isTouchStart = false;
let lastCoordinates = null;
let isTap = false;
// whether to send mouse event
let mouseEvent = true;
let mouseEventsOnly = false;
/**
* Called when listener is first started up.
* The listener sends its unique window ID and its current URI to the actor.
@ -111,7 +108,6 @@ function startListeners() {
addMessageListenerId("Marionette:singleTap", singleTap);
addMessageListenerId("Marionette:actionChain", actionChain);
addMessageListenerId("Marionette:multiAction", multiAction);
addMessageListenerId("Marionette:sendMouseEvent", sendMouseEvent);
addMessageListenerId("Marionette:goUrl", goUrl);
addMessageListenerId("Marionette:getUrl", getUrl);
addMessageListenerId("Marionette:getTitle", getTitle);
@ -186,7 +182,6 @@ function deleteSession(msg) {
removeMessageListenerId("Marionette:singleTap", singleTap);
removeMessageListenerId("Marionette:actionChain", actionChain);
removeMessageListenerId("Marionette:multiAction", multiAction);
removeMessageListenerId("Marionette:sendMouseEvent", sendMouseEvent);
removeMessageListenerId("Marionette:goUrl", goUrl);
removeMessageListenerId("Marionette:getTitle", getTitle);
removeMessageListenerId("Marionette:getPageSource", getPageSource);
@ -224,7 +219,6 @@ function deleteSession(msg) {
// reset frame to the top-most frame
curWindow = content;
curWindow.focus();
touches = [];
touchIds = {};
}
@ -277,6 +271,7 @@ function sendError(message, status, trace, command_id) {
function resetValues() {
sandbox = null;
curWindow = content;
mouseEventsOnly = false;
}
/*
@ -539,20 +534,6 @@ function executeWithCallback(msg, useFinish) {
}
}
/**
* This function sets a value for mouseEvent to decide if we want to send mouse events
*/
function sendMouseEvent(msg) {
let command_id = msg.json.command_id;
if (typeof msg.json.value === 'boolean') {
mouseEvent = msg.json.value;
sendOk(msg.json.command_id);
}
else {
sendError("Json value is not boolean as expected", 500, null, command_id);
}
}
/**
* This function creates a touch event given a touch type and a touch
*/
@ -569,209 +550,42 @@ function emitTouchEvent(type, touch) {
* detail is the number of clicks, button notes the mouse button
* elClientX and elClientY are the coordinates of the mouse relative to the viewport
*/
function emitMouseEvent(doc, type, detail, button, elClientX, elClientY) {
function emitMouseEvent(doc, type, elClientX, elClientY, detail, button) {
detail = detail || 1;
button = button || 0;
var win = doc.defaultView;
// Figure out the element the mouse would be over at (x, y)
var target = doc.elementFromPoint(elClientX, elClientY);
utils.synthesizeMouse(target, win.mozInnerScreenX, win.mozInnerScreenY, {type: type, button: button, clickCount: detail}, win);
utils.synthesizeMouseAtPoint(elClientX, elClientY, {type: type, button: button, clickCount: detail}, win);
}
/**
* This function create a mouse and emit mouse events
* @param 'xt' and 'yt' are functions of t that specify the mouse coordinates at time t
* Helper function that perform a mouse tap
*/
function mouse(doc, duration, xt, yt, then, detail, button) {
detail = detail || 1;
button = button || 0;
var x = xt;
if (typeof xt !== 'function') {
x = function(t) {
return xt[0] + t / duration * (xt[1] - xt[0]);
}
}
var y = yt;
if (typeof yt !== 'function') {
y = function(t) {
return yt[0] + t / duration * (yt[1] - yt[0]);
}
}
// viewport coordinates
var clientX = Math.round(x(0)), clientY = Math.round(y(0));
// Remember the coordinates
var lastX = clientX, lastY = clientY;
emitMouseEvent(doc, 'mousedown', detail, button, clientX, clientY);
// now send a sequence of mousemove events followed by mouse up
let startTime = Date.now();
checkTimer.initWithCallback(nextEvent, EVENT_INTERVAL, Ci.nsITimer.TYPE_ONE_SHOT);
function nextEvent() {
// figure out if we've sent all the mousemove events
var time = Date.now();
var dt = time - startTime;
let last = dt + EVENT_INTERVAL / 2 > duration;
// New coordinates of the touch
clientX = Math.round(x(dt));
clientY = Math.round(y(dt));
// If we moved, send a move event
if (clientX !== lastX || clientY !== lastY) { // If we moved
lastX = clientX;
lastY = clientY;
emitMouseEvent(doc, 'mousemove', detail, button, clientX, clientY);
}
// If this was the last move, send a mouse up and call the callback
// Otherwise, schedule the next move event
if (last) {
emitMouseEvent(doc, 'mouseup', detail, button, lastX, lastY);
if (then) {
checkTimer.initWithCallback(then, 0, Ci.nsITimer.TYPE_ONE_SHOT);
}
}
else {
checkTimer.initWithCallback(nextEvent, EVENT_INTERVAL, Ci.nsITimer.TYPE_ONE_SHOT);
}
}
function mousetap(doc, x, y) {
emitMouseEvent(doc, 'mousemove', x, y);
emitMouseEvent(doc, 'mousedown', x, y);
emitMouseEvent(doc, 'mouseup', x, y);
}
/**
* This function creates a touch and emit touch events
* @param 'xt' and 'yt' are two-element array [from, to] and then is a callback that will be invoked after touchend event is sent
*/
function touch(target, duration, xt, yt, then) {
let doc = target.ownerDocument;
let win = doc.defaultView;
let touchId = nextTouchId++;
let x = xt;
if (typeof xt !== 'function') {
x = function(t) { return xt[0] + t / duration * (xt[1] - xt[0]); };
}
let y = yt;
if (typeof yt !== 'function') {
y = function(t) { return yt[0] + t / duration * (yt[1] - yt[0]); };
}
// viewport coordinates
let clientX = Math.round(x(0)), clientY = Math.round(y(0));
// document coordinates
let pageX = clientX + win.pageXOffset,
pageY = clientY + win.pageYOffset;
// screen coordinates
let screenX = clientX + win.mozInnerScreenX,
screenY = clientY + win.mozInnerScreenY;
// Remember the coordinates
let lastX = clientX, lastY = clientY;
// Create the touch object
let touch = doc.createTouch(win, target, touchId,
pageX, pageY,
screenX, screenY,
clientX, clientY);
// Add this new touch to the list of touches
touches.push(touch);
// Send the start event
emitTouchEvent('touchstart', touch);
let startTime = Date.now();
checkTimer.initWithCallback(nextEvent, EVENT_INTERVAL, Ci.nsITimer.TYPE_ONE_SHOT);
function nextEvent() {
// Figure out if this is the last of the touchmove events
let time = Date.now();
let dt = time - startTime;
let last = dt + EVENT_INTERVAL / 2 > duration;
// Find our touch object in the touches[] array.
// Note that its index may have changed since we pushed it
let touchIndex = touches.indexOf(touch);
// If this is the last move event, make sure we move all the way
if (last)
dt = duration;
// New coordinates of the touch
clientX = Math.round(x(dt));
clientY = Math.round(y(dt));
// If we've moved, send a move event
if (clientX !== lastX || clientY !== lastY) { // If we moved
lastX = clientX;
lastY = clientY;
pageX = clientX + win.pageXOffset;
pageY = clientY + win.pageYOffset;
screenX = clientX + win.mozInnerScreenX;
screenY = clientY + win.mozInnerScreenY;
// Since we moved, we've got to create a new Touch object
// with the new coordinates
touch = doc.createTouch(win, target, touchId,
pageX, pageY,
screenX, screenY,
clientX, clientY);
// Replace the old touch object with the new one
touches[touchIndex] = touch;
// And send the touchmove event
emitTouchEvent('touchmove', touch);
}
// If that was the last move, send the touchend event
// and call the callback
if (last) {
touches.splice(touchIndex, 1);
emitTouchEvent('touchend', touch);
if (then)
checkTimer.initWithCallback(then, 0, Ci.nsITimer.TYPE_ONE_SHOT);
}
// Otherwise, schedule the next event
else {
checkTimer.initWithCallback(nextEvent, EVENT_INTERVAL, Ci.nsITimer.TYPE_ONE_SHOT);
}
}
}
/**
* This function generates the coordinates of the element
* @param 'x0', 'y0', 'x1', and 'y1' are the relative to the target.
* This function generates a pair of coordinates relative to the viewport given a
* target element and coordinates relative to that element's top-left corner.
* @param 'x', and 'y' are the relative to the target.
* If they are not specified, then the center of the target is used.
*/
function coordinates(target, x0, y0, x1, y1) {
let coords = {};
function coordinates(target, x, y) {
let box = target.getBoundingClientRect();
let tx0 = typeof x0;
let ty0 = typeof y0;
let tx1 = typeof x1;
let ty1 = typeof y1;
function percent(s, x) {
s = s.trim();
let f = parseFloat(s);
if (s[s.length - 1] === '%')
f = f * x / 100;
return f;
if (x == null) {
x = box.width / 2;
}
function relative(s, x) {
let factor;
if (s[0] === '+')
factor = 1;
else
factor = -1;
return factor * percent(s.substring(1), x);
}
if (tx0 === 'number')
coords.x0 = box.left + x0;
else if (tx0 === 'string')
coords.x0 = box.left + percent(x0, box.width);
//check tx1 point
if (tx1 === 'number')
coords.x1 = box.left + x1;
else if (tx1 === 'string') {
x1 = x1.trim();
if (x1[0] === '+' || x1[0] === '-')
coords.x1 = coords.x0 + relative(x1, box.width);
else
coords.x1 = box.left + percent(x1, box.width);
}
// check ty0
if (ty0 === 'number')
coords.y0 = box.top + y0;
else if (ty0 === 'string')
coords.y0 = box.top + percent(y0, box.height);
//check ty1
if (ty1 === 'number')
coords.y1 = box.top + y1;
else if (ty1 === 'string') {
y1 = y1.trim();
if (y1[0] === '+' || y1[0] === '-')
coords.y1 = coords.y0 + relative(y1, box.height);
else
coords.y1 = box.top + percent(y1, box.height);
if (y == null) {
y = box.height / 2;
}
let coords = {};
coords.x = box.left + x;
coords.y = box.top + y;
return coords;
}
@ -790,7 +604,7 @@ function elementInViewport(el) {
/**
* This function throws the visibility of the element error
*/
function checkVisible(el, command_id) {
function checkVisible(el) {
//check if the element is visible
let visible = utils.isElementDisplayed(el);
if (!visible) {
@ -814,35 +628,110 @@ function checkVisible(el, command_id) {
return true;
}
//x and y are coordinates relative to the viewport
function generateEvents(type, x, y, touchId, target) {
lastCoordinates = [x, y];
let doc = curWindow.document;
switch (type) {
case 'tap':
if (mouseEventsOnly) {
mousetap(target.ownerDocument, x, y);
}
else {
let touchId = nextTouchId++;
let touch = createATouch(target, x, y, touchId);
emitTouchEvent('touchstart', touch);
emitTouchEvent('touchend', touch);
mousetap(target.ownerDocument, x, y);
}
lastCoordinates = null;
break;
case 'press':
isTap = true;
if (mouseEventsOnly) {
emitMouseEvent(doc, 'mousemove', x, y);
emitMouseEvent(doc, 'mousedown', x, y);
}
else {
let touchId = nextTouchId++;
let touch = createATouch(target, x, y, touchId);
emitTouchEvent('touchstart', touch);
touchIds[touchId] = touch;
return touchId;
}
break;
case 'release':
if (mouseEventsOnly) {
emitMouseEvent(doc, 'mouseup', lastCoordinates[0], lastCoordinates[1]);
}
else {
let touch = touchIds[touchId];
touch = createATouch(touch.target, lastCoordinates[0], lastCoordinates[1], touchId);
emitTouchEvent('touchend', touch);
if (isTap) {
mousetap(touch.target.ownerDocument, touch.clientX, touch.clientY);
}
delete touchIds[touchId];
}
isTap = false;
lastCoordinates = null;
break;
case 'cancel':
isTap = false;
if (mouseEventsOnly) {
emitMouseEvent(doc, 'mouseup', lastCoordinates[0], lastCoordinates[1]);
}
else {
emitTouchEvent('touchcancel', touchIds[touchId]);
delete touchIds[touchId];
}
lastCoordinates = null;
break;
case 'move':
isTap = false;
if (mouseEventsOnly) {
emitMouseEvent(doc, 'mousemove', x, y);
}
else {
touch = createATouch(touchIds[touchId].target, x, y, touchId);
touchIds[touchId] = touch;
emitTouchEvent('touchmove', touch);
}
break;
case 'contextmenu':
isTap = false;
let event = curWindow.document.createEvent('HTMLEvents');
event.initEvent('contextmenu', true, true);
if (mouseEventsOnly) {
target = doc.elementFromPoint(lastCoordinates[0], lastCoordinates[1]);
}
else {
target = touchIds[touchId].target;
}
target.dispatchEvent(event);
break;
default:
throw {message:"Unknown event type: " + type, code: 500, stack:null};
}
}
/**
* Function that perform a single tap
*/
function singleTap(msg) {
let command_id = msg.json.command_id;
let el;
try {
el = elementManager.getKnownElement(msg.json.value, curWindow);
let x = msg.json.corx;
let y = msg.json.cory;
if (!checkVisible(el, command_id)) {
sendError("Element is not currently visible and may not be manipulated", 11, null, command_id);
return;
let el = elementManager.getKnownElement(msg.json.value, curWindow);
// after this block, the element will be scrolled into view
if (!checkVisible(el)) {
sendError("Element is not currently visible and may not be manipulated", 11, null, command_id);
return;
}
if (x == null) {
x = '50%';
}
if (y == null) {
y = '50%';
}
let c = coordinates(el, x, y);
if (mouseEvent) {
touch(el, 25, [c.x0, c.x0], [c.y0, c.y0], function() {
mousetap(el, 25, c.x0, c.y0, 1, 0, null);
});
}
else {
touch(el, 25, [c.x0, c.x0], [c.y0, c.y0], null);
if (!curWindow.document.createTouch) {
mouseEventsOnly = true;
}
let c = coordinates(el, msg.json.corx, msg.json.cory);
generateEvents('tap', c.x, c.y, null, el);
sendOk(msg.json.command_id);
}
catch (e) {
@ -850,171 +739,103 @@ function singleTap(msg) {
}
}
/**
* Function that perform a mouse tap
*/
function mousetap(target, duration, x, y, detail, button, then) {
var doc = target.ownerDocument;
detail = detail || 1;
button = button || 0;
emitMouseEvent(doc, 'mousemove', detail, button, x, y);
mouse(doc, duration, [x, x], [y, y], then, detail, button);
}
/**
* Function to create a touch based on the element
* corx and cory are related to the el, id is the touchId
* corx and cory are relative to the viewport, id is the touchId
*/
function createATouch(el, corx, cory, id) {
function createATouch(el, corx, cory, touchId) {
let doc = el.ownerDocument;
let win = doc.defaultView;
if (corx == null) {
corx = '50%';
}
if (cory == null){
cory = '50%';
}
// corx and cory are relative to the el target. They must be within the same viewport
// c are the coordinates relative to the current viewport
let c = coordinates(el, corx, cory);
let clientX = Math.round(c.x0),
clientY = Math.round(c.y0);
let clientX = corx;
let clientY = cory;
let pageX = clientX + win.pageXOffset,
pageY = clientY + win.pageYOffset;
let screenX = clientX + win.mozInnerScreenX,
screenY = clientY + win.mozInnerScreenY;
let atouch = doc.createTouch(win, el, id, pageX, pageY, screenX, screenY, clientX, clientY);
let atouch = doc.createTouch(win, el, touchId, pageX, pageY, screenX, screenY, clientX, clientY);
return atouch;
}
/**
* Function to emit touch events for each finger. e.g. finger=[['press', id], ['wait', 5], ['release']]
* touchId represents the finger id, i keeps track of the current action of the finger
* touchId represents the finger id, i keeps track of the current action of the chain
*/
function actions(finger, touchId, command_id, i){
function actions(chain, touchId, command_id, i) {
if (typeof i === "undefined") {
i = 0;
}
if (i == finger.length) {
if (i == chain.length) {
sendResponse({value: touchId}, command_id);
return;
}
let pack = finger[i];
let pack = chain[i];
let command = pack[0];
// el has the id
let el;
let corx;
let cory;
let touch;
let contextmenu = false;
let c;
i++;
if (command != 'press') {
//if mouseEventsOnly, then touchIds isn't used
if (!(touchId in touchIds) && !mouseEventsOnly) {
sendError("Element has not been pressed", 500, null, command_id);
return;
}
}
switch(command) {
case 'press':
if (lastTouch != null) {
touch = lastTouch;
emitTouchEvent('touchcancel', touch);
lastTouch = null;
sendError("Invalid Command: long_press cannot follow an active touch event", 500, null, command_id);
if (lastCoordinates) {
generateEvents('cancel', lastCoordinates[0], lastCoordinates[1], touchId);
sendError("Invalid Command: press cannot follow an active touch event", 500, null, command_id);
return;
}
el = elementManager.getKnownElement(pack[1], curWindow);
corx = pack[2];
cory = pack[3];
// after this block, the element will be scrolled into view
if (!checkVisible(el, command_id)) {
if (!checkVisible(el)) {
sendError("Element is not currently visible and may not be manipulated", 11, null, command_id);
return;
}
touch = createATouch(el, corx, cory, touchId);
lastTouch = touch;
isTouchStart = true;
emitTouchEvent('touchstart', touch);
actions(finger,touchId, command_id, i);
c = coordinates(el, pack[2], pack[3]);
touchId = generateEvents('press', c.x, c.y, null, el);
actions(chain, touchId, command_id, i);
break;
case 'release':
if (lastTouch == null) {
sendError("Element has not been pressed: no such element", 7, null, command_id);
return;
}
touch = lastTouch;
lastTouch = null;
emitTouchEvent('touchend', touch);
if (isTouchStart && mouseEvent) {
emitMouseEvent(touch.target.ownerDocument, 'mousemove', 1, 0, touch.clientX, touch.clientY);
emitMouseEvent(touch.target.ownerDocument, 'mousedown', 1, 0, touch.clientX, touch.clientY);
emitMouseEvent(touch.target.ownerDocument, 'mouseup', 1, 0, touch.clientX, touch.clientY);
}
isTouchStart = false;
actions(finger, touchId, command_id, i);
generateEvents('release', lastCoordinates[0], lastCoordinates[1], touchId);
actions(chain, null, command_id, i);
break;
case 'move':
if (lastTouch == null) {
sendError("Element has not been pressed: no such element", 7, null, command_id);
return;
}
el = elementManager.getKnownElement(pack[1], curWindow);
let boxTarget = el.getBoundingClientRect();
let startElement = lastTouch.target;
let boxStart = startElement.getBoundingClientRect();
corx = boxTarget.left - boxStart.left + boxTarget.width * 0.5;
cory = boxTarget.top - boxStart.top + boxTarget.height * 0.5;
touch = createATouch(startElement, corx, cory, touchId);
lastTouch = touch;
isTouchStart = false;
emitTouchEvent('touchmove', touch);
actions(finger, touchId, command_id, i);
c = coordinates(el);
generateEvents('move', c.x, c.y, touchId);
actions(chain, touchId, command_id, i);
break;
case 'moveByOffset':
if (lastTouch == null) {
sendError("Element has not been pressed: no such element", 7, null, command_id);
return;
}
el = lastTouch.target;
let doc = el.ownerDocument;
let win = doc.defaultView;
let clientX = lastTouch.clientX + pack[1],
clientY = lastTouch.clientY + pack[2];
let pageX = clientX + win.pageXOffset,
pageY = clientY + win.pageYOffset;
let screenX = clientX + win.mozInnerScreenX,
screenY = clientY + win.mozInnerScreenY;
touch = doc.createTouch(win, el, touchId, pageX, pageY, screenX, screenY, clientX, clientY);
lastTouch = touch;
isTouchStart = false;
emitTouchEvent('touchmove', touch);
actions(finger, touchId, command_id, i);
generateEvents('move', lastCoordinates[0] + pack[1], lastCoordinates[1] + pack[2], touchId);
actions(chain, touchId, command_id, i);
break;
case 'wait':
if (pack[1] != null ) {
let time = pack[1]*1000;
// standard waiting time to fire contextmenu
let standard = Services.prefs.getIntPref("ui.click_hold_context_menus.delay");
if (time >= standard && isTouchStart && !contextmenu) {
finger.splice(i, 0, ['longPress'], ['wait', (time-standard)/1000]);
let standard = 750;
try {
standard = Services.prefs.getIntPref("ui.click_hold_context_menus.delay");
}
catch (e){}
if (time >= standard && isTap) {
chain.splice(i, 0, ['longPress'], ['wait', (time-standard)/1000]);
time = standard;
}
checkTimer.initWithCallback(function(){actions(finger, touchId, command_id, i);}, time, Ci.nsITimer.TYPE_ONE_SHOT);
checkTimer.initWithCallback(function(){actions(chain, touchId, command_id, i);}, time, Ci.nsITimer.TYPE_ONE_SHOT);
}
else {
actions(finger, touchId, command_id, i);
actions(chain, touchId, command_id, i);
}
break;
case 'cancel':
touch = lastTouch;
emitTouchEvent('touchcancel', touch);
lastTouch = null;
isTouchStart = false;
actions(finger, touchId, command_id, i);
generateEvents('cancel', lastCoordinates[0], lastCoordinates[1], touchId);
actions(chain, touchId, command_id, i);
break;
case 'longPress':
isTouchStart = false;
contextmenu = true;
let event = curWindow.document.createEvent('HTMLEvents');
event.initEvent('contextmenu',
true,
true);
lastTouch.target.dispatchEvent(event);
actions(finger, touchId, command_id, i);
generateEvents('contextmenu', lastCoordinates[0], lastCoordinates[1], touchId);
actions(chain, touchId, command_id, i);
break;
}
}
@ -1032,6 +853,9 @@ function actionChain(msg) {
if (touchId == null) {
touchId = nextTouchId++;
}
if (!curWindow.document.createTouch) {
mouseEventsOnly = true;
}
actions(commandArray, touchId, command_id);
}
catch (e) {
@ -1102,6 +926,7 @@ function setDispatch(batches, touches, command_id, batchIndex) {
let touchIndex;
let waitTime = 0;
let maxTime = 0;
let c;
batchIndex++;
// loop through the batch
for (let i = 0; i < batch.length; i++) {
@ -1111,14 +936,8 @@ function setDispatch(batches, touches, command_id, batchIndex) {
switch (command) {
case 'press':
el = elementManager.getKnownElement(pack[2], curWindow);
// after this block, the element will be scrolled into view
if (!checkVisible(el, command_id)) {
sendError("Element is not currently visible and may not be manipulated", 11, null, command_id);
return;
}
corx = pack[3];
cory = pack[4];
touch = createATouch(el, corx, cory, touchId);
c = coordinates(el, pack[3], pack[4]);
touch = createATouch(el, c.x, c.y, touchId);
multiLast[touchId] = touch;
touches.push(touch);
emitMultiEvents('touchstart', touch, touches);
@ -1132,15 +951,8 @@ function setDispatch(batches, touches, command_id, batchIndex) {
break;
case 'move':
el = elementManager.getKnownElement(pack[2], curWindow);
lastTouch = multiLast[touchId];
let boxTarget = el.getBoundingClientRect();
let startTarget = lastTouch.target;
let boxStart = startTarget.getBoundingClientRect();
// note here corx and cory are relative to the target, not the viewport
// we always want to touch the center of the element if the element is specified
corx = boxTarget.left - boxStart.left + boxTarget.width * 0.5;
cory = boxTarget.top - boxStart.top + boxTarget.height * 0.5;
touch = createATouch(startTarget, corx, cory, touchId);
c = coordinates(el);
touch = createATouch(multiLast[touchId].target, c.x, c.y, touchId);
touchIndex = touches.indexOf(lastTouch);
touches[touchIndex] = touch;
multiLast[touchId] = touch;
@ -1355,7 +1167,7 @@ function clickElement(msg) {
let el;
try {
el = elementManager.getKnownElement(msg.json.element, curWindow);
if (checkVisible(el, command_id)) {
if (checkVisible(el)) {
if (utils.isElementEnabled(el)) {
utils.synthesizeMouseAtCenter(el, {}, el.ownerDocument.defaultView)
}
@ -1502,7 +1314,7 @@ function sendKeysToElement(msg) {
let command_id = msg.json.command_id;
try {
let el = elementManager.getKnownElement(msg.json.element, curWindow);
if (checkVisible(el, command_id)) {
if (checkVisible(el)) {
utils.type(curWindow.document, el, msg.json.value.join(""), true);
sendOk(command_id);
}

View File

@ -292,15 +292,9 @@ nsNavHistoryResultNode::GetGeneratingOptions()
return nullptr;
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsNavHistoryContainerResultNode, nsNavHistoryResultNode)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mResult)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChildren)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsNavHistoryContainerResultNode, nsNavHistoryResultNode)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResult)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildren)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_INHERITED_2(nsNavHistoryContainerResultNode, nsNavHistoryResultNode,
mResult,
mChildren)
NS_IMPL_ADDREF_INHERITED(nsNavHistoryContainerResultNode, nsNavHistoryResultNode)
NS_IMPL_RELEASE_INHERITED(nsNavHistoryContainerResultNode, nsNavHistoryResultNode)

View File

@ -160,6 +160,9 @@ using namespace mozilla;
#define DEFAULT_SHUTDOWN_COLLECTIONS 5
// One to do the freeing, then another to detect there is no more work to do.
#define NORMAL_SHUTDOWN_COLLECTIONS 2
#if defined(XP_WIN)
// Defined in nsThreadManager.cpp.
extern DWORD gTLSThreadIDIndex;
@ -2538,6 +2541,7 @@ nsCycleCollector::nsCycleCollector(CCThreadingModel aModel) :
nsCycleCollector::~nsCycleCollector()
{
NS_ASSERTION(!mRunner, "Destroying cycle collector without destroying its runner, may leak");
NS_UnregisterMemoryMultiReporter(mReporter);
}
@ -2753,6 +2757,8 @@ nsCycleCollector::ShutdownCollect(nsICycleCollectorListener *aListener)
return;
for (uint32_t i = 0; i < DEFAULT_SHUTDOWN_COLLECTIONS; ++i) {
NS_WARN_IF_FALSE(i < NORMAL_SHUTDOWN_COLLECTIONS, "Extra shutdown CC");
// Synchronous cycle collection. Always force a JS GC beforehand.
FixGrayBits(true);
if (aListener && NS_FAILED(aListener->Begin()))

View File

@ -1172,6 +1172,56 @@ struct Skippable
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f8) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
#define NS_IMPL_CYCLE_COLLECTION_INHERITED_9(_class, _base, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9) \
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(_class, _base) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f1) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f2) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f3) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f4) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f5) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f6) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f7) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f8) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f9) \
NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(_class, _base) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f1) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f2) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f3) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f4) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f5) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f6) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f7) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f8) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f9) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
#define NS_IMPL_CYCLE_COLLECTION_INHERITED_10(_class, _base, _f1, _f2, _f3, _f4, _f5, _f6, _f7, _f8, _f9, _f10) \
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(_class, _base) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f1) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f2) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f3) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f4) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f5) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f6) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f7) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f8) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f9) \
NS_IMPL_CYCLE_COLLECTION_UNLINK(_f10) \
NS_IMPL_CYCLE_COLLECTION_UNLINK_END \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(_class, _base) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f1) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f2) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f3) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f4) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f5) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f6) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f7) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f8) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f9) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_f10) \
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
#define NS_CYCLE_COLLECTION_NOTE_EDGE_NAME CycleCollectionNoteEdgeName
#endif // nsCycleCollectionParticipant_h__

View File

@ -9,22 +9,6 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
STACK_FAILURE_TESTCASES = \
TestStack.cpp \
TestStackTemplate.cpp \
StackNoConstructor.cpp \
StackVector.cpp \
StackConditional.cpp \
StackAggrInit.cpp \
StackCondBad.cpp \
StackFalsePositive.cpp \
$(NULL)
STACK_PASS_TESTCASES = \
StackPlacementNewOK.cpp \
StackCond.cpp \
$(NULL)
OUTPARAMS_WARNING_TESTCASES = \
e1.cpp \
e4.cpp \
@ -115,14 +99,12 @@ STATIC_FAILURE_TESTCASES = \
STATIC_WARNING_TESTCASES = \
$(OUTPARAMS_WARNING_TESTCASES) \
$(STACK_FAILURE_TESTCASES) \
$(STATIC_INIT_WARNING_TESTCASES) \
$(NULL)
STATIC_PASS_TESTCASES = \
$(OUTPARAMS_NS_FAILED_TESTCASES) \
$(OUTPARAMS_PASS_TESTCASES) \
$(STACK_PASS_TESTCASES) \
$(FLOW_PASS_TESTCASES) \
$(MUST_OVERRIDE_PASS_TESTCASES) \
$(OVERRIDE_PASS_TESTCASES) \

View File

@ -1,12 +0,0 @@
#include "nscore.h"
#include "nsAutoPtr.h"
class NS_STACK_CLASS A
{
int i;
};
void Foo()
{
nsAutoPtr<A> a(new A);
}

View File

@ -1,12 +0,0 @@
#include "nscore.h"
struct A
{
};
A* tfunc(int len)
{
A arr[5];
A* a = len <= 5 ? arr : new A[len];
return a;
}

View File

@ -1,12 +0,0 @@
#include "nscore.h"
struct NS_STACK_CLASS A
{
};
A* tfunc(int len)
{
A arr[5];
A* a = len <= 5 ? arr : new A[len];
return a;
}

View File

@ -1,15 +0,0 @@
#define NS_STACK_CLASS __attribute__((user("NS_stack")))
struct NS_STACK_CLASS A
{
int i;
};
void
GetIt(int i)
{
A *a;
if (i)
a = new A();
}

View File

@ -1,12 +0,0 @@
#include <new>
#include "nscore.h"
struct NS_STACK_CLASS A
{
};
void foo() {
A* a;
void* v = ::operator new(16);
a = (A*) v; // tricks analysis
}

View File

@ -1,11 +0,0 @@
#include "nscore.h"
struct NS_STACK_CLASS A
{
int i;
};
void* Foo()
{
return new A();
}

View File

@ -1,15 +0,0 @@
#include "nscore.h"
#include NEW_H
struct NS_STACK_CLASS A
{
int i;
};
int Foo()
{
char buf[sizeof(A)];
A *a = new(&buf) A;
return a->i;
}

View File

@ -1,12 +0,0 @@
#include "nscore.h"
struct NS_STACK_CLASS A
{
int i;
};
void* Foo()
{
A *a = new A[8];
return a;
}

View File

@ -1,15 +0,0 @@
#include "nscore.h"
struct NS_STACK_CLASS A
{
// BUG: currently classes which are marked NS_STACK_CLASS must have a
// constructor
A();
int i;
};
void* Foo()
{
return new A();
}

View File

@ -1,14 +0,0 @@
#include "nscore.h"
template<class T>
struct NS_STACK_CLASS A
{
A();
T i;
};
void *Foo()
{
return new A<int>();
}