mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
merge
This commit is contained in:
commit
36eee9eb95
@ -2188,9 +2188,7 @@ nsAccessible::GetRelationByType(PRUint32 aRelationType,
|
||||
// HTML form controls implements nsIFormControl interface.
|
||||
nsCOMPtr<nsIFormControl> control(do_QueryInterface(mContent));
|
||||
if (control) {
|
||||
nsCOMPtr<nsIDOMHTMLFormElement> htmlform;
|
||||
control->GetForm(getter_AddRefs(htmlform));
|
||||
nsCOMPtr<nsIForm> form(do_QueryInterface(htmlform));
|
||||
nsCOMPtr<nsIForm> form(do_QueryInterface(control->GetFormElement()));
|
||||
if (form) {
|
||||
nsCOMPtr<nsIContent> formContent =
|
||||
do_QueryInterface(form->GetDefaultSubmitElement());
|
||||
|
@ -3101,6 +3101,7 @@
|
||||
role="presentation"/>
|
||||
<xul:toolbarbutton anonid="close-button"
|
||||
tabindex="-1"
|
||||
clickthrough="never"
|
||||
class="tab-close-button"/>
|
||||
</content>
|
||||
|
||||
|
@ -222,6 +222,11 @@ public:
|
||||
*/
|
||||
static PRBool IsCallerTrustedForCapability(const char* aCapability);
|
||||
|
||||
/**
|
||||
* Returns the parent node of aChild crossing document boundaries.
|
||||
*/
|
||||
static nsINode* GetCrossDocParentNode(nsINode* aChild);
|
||||
|
||||
/**
|
||||
* Do not ever pass null pointers to this method. If one of your
|
||||
* nsIContents is null, you have to decide for yourself what
|
||||
|
@ -170,15 +170,11 @@ nsFormContentList::nsFormContentList(nsIDOMHTMLFormElement *aForm,
|
||||
// move elements that belong to mForm into this content list
|
||||
|
||||
PRUint32 i, length = 0;
|
||||
nsCOMPtr<nsIDOMNode> item;
|
||||
|
||||
aContentList.GetLength(&length);
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
aContentList.Item(i, getter_AddRefs(item));
|
||||
|
||||
nsCOMPtr<nsIContent> c(do_QueryInterface(item));
|
||||
|
||||
nsIContent *c = aContentList.GetNodeAt(i);
|
||||
if (c && nsContentUtils::BelongsInForm(aForm, c)) {
|
||||
AppendElement(c);
|
||||
}
|
||||
|
@ -1521,6 +1521,21 @@ nsContentUtils::IsCallerTrustedForWrite()
|
||||
return IsCallerTrustedForCapability("UniversalBrowserWrite");
|
||||
}
|
||||
|
||||
// static
|
||||
nsINode*
|
||||
nsContentUtils::GetCrossDocParentNode(nsINode* aChild)
|
||||
{
|
||||
NS_PRECONDITION(aChild, "The child is null!");
|
||||
|
||||
nsINode* parent = aChild->GetNodeParent();
|
||||
if (parent || !aChild->IsNodeOfType(nsINode::eDOCUMENT))
|
||||
return parent;
|
||||
|
||||
nsIDocument* doc = static_cast<nsIDocument*>(aChild);
|
||||
nsIDocument* parentDoc = doc->GetParentDocument();
|
||||
return parentDoc ? parentDoc->FindContentForSubDocument(doc) : nsnull;
|
||||
}
|
||||
|
||||
// static
|
||||
PRBool
|
||||
nsContentUtils::ContentIsDescendantOf(const nsINode* aPossibleDescendant,
|
||||
@ -1549,16 +1564,7 @@ nsContentUtils::ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant,
|
||||
do {
|
||||
if (aPossibleDescendant == aPossibleAncestor)
|
||||
return PR_TRUE;
|
||||
nsINode* parent = aPossibleDescendant->GetNodeParent();
|
||||
if (!parent && aPossibleDescendant->IsNodeOfType(nsINode::eDOCUMENT)) {
|
||||
nsIDocument* doc = static_cast<nsIDocument*>(aPossibleDescendant);
|
||||
nsIDocument* parentDoc = doc->GetParentDocument();
|
||||
aPossibleDescendant = parentDoc ?
|
||||
parentDoc->FindContentForSubDocument(doc) : nsnull;
|
||||
}
|
||||
else {
|
||||
aPossibleDescendant = parent;
|
||||
}
|
||||
aPossibleDescendant = GetCrossDocParentNode(aPossibleDescendant);
|
||||
} while (aPossibleDescendant);
|
||||
|
||||
return PR_FALSE;
|
||||
@ -1915,11 +1921,10 @@ static inline void KeyAppendAtom(nsIAtom* aAtom, nsACString& aKey)
|
||||
KeyAppendString(nsAtomCString(aAtom), aKey);
|
||||
}
|
||||
|
||||
static inline PRBool IsAutocompleteOff(nsIDOMElement* aElement)
|
||||
static inline PRBool IsAutocompleteOff(nsIContent* aElement)
|
||||
{
|
||||
nsAutoString autocomplete;
|
||||
aElement->GetAttribute(NS_LITERAL_STRING("autocomplete"), autocomplete);
|
||||
return autocomplete.LowerCaseEqualsLiteral("off");
|
||||
return aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::autocomplete,
|
||||
NS_LITERAL_STRING("off"), eIgnoreCase);
|
||||
}
|
||||
|
||||
/*static*/ nsresult
|
||||
@ -1948,8 +1953,7 @@ nsContentUtils::GenerateStateKey(nsIContent* aContent,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(aContent));
|
||||
if (element && IsAutocompleteOff(element)) {
|
||||
if (IsAutocompleteOff(aContent)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1995,10 +1999,8 @@ nsContentUtils::GenerateStateKey(nsIContent* aContent,
|
||||
|
||||
// If in a form, add form name / index of form / index in form
|
||||
PRInt32 index = -1;
|
||||
nsCOMPtr<nsIDOMHTMLFormElement> formElement;
|
||||
control->GetForm(getter_AddRefs(formElement));
|
||||
Element *formElement = control->GetFormElement();
|
||||
if (formElement) {
|
||||
|
||||
if (IsAutocompleteOff(formElement)) {
|
||||
aKey.Truncate();
|
||||
return NS_OK;
|
||||
@ -2007,8 +2009,7 @@ nsContentUtils::GenerateStateKey(nsIContent* aContent,
|
||||
KeyAppendString(NS_LITERAL_CSTRING("f"), aKey);
|
||||
|
||||
// Append the index of the form in the document
|
||||
nsCOMPtr<nsIContent> formContent(do_QueryInterface(formElement));
|
||||
index = htmlForms->IndexOf(formContent, PR_FALSE);
|
||||
index = htmlForms->IndexOf(formElement, PR_FALSE);
|
||||
if (index <= -1) {
|
||||
//
|
||||
// XXX HACK this uses some state that was dumped into the document
|
||||
@ -2034,7 +2035,7 @@ nsContentUtils::GenerateStateKey(nsIContent* aContent,
|
||||
|
||||
// Append the form name
|
||||
nsAutoString formName;
|
||||
formElement->GetName(formName);
|
||||
formElement->GetAttr(kNameSpaceID_None, nsGkAtoms::name, formName);
|
||||
KeyAppendString(formName, aKey);
|
||||
|
||||
} else {
|
||||
|
@ -72,11 +72,10 @@ nsDOMAttributeMap::Init()
|
||||
* Clear map pointer for attributes.
|
||||
*/
|
||||
PLDHashOperator
|
||||
RemoveMapRef(nsAttrHashKey::KeyType aKey, nsCOMPtr<nsIDOMNode>& aData, void* aUserArg)
|
||||
RemoveMapRef(nsAttrHashKey::KeyType aKey, nsRefPtr<nsDOMAttribute>& aData,
|
||||
void* aUserArg)
|
||||
{
|
||||
nsCOMPtr<nsIAttribute> attr(do_QueryInterface(aData));
|
||||
NS_ASSERTION(attr, "non-nsIAttribute somehow made it into the hashmap?!");
|
||||
attr->SetMap(nsnull);
|
||||
aData->SetMap(nsnull);
|
||||
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
@ -101,12 +100,13 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
|
||||
PLDHashOperator
|
||||
TraverseMapEntry(nsAttrHashKey::KeyType aKey, nsCOMPtr<nsIDOMNode>& aData, void* aUserArg)
|
||||
TraverseMapEntry(nsAttrHashKey::KeyType aKey, nsRefPtr<nsDOMAttribute>& aData,
|
||||
void* aUserArg)
|
||||
{
|
||||
nsCycleCollectionTraversalCallback *cb =
|
||||
static_cast<nsCycleCollectionTraversalCallback*>(aUserArg);
|
||||
|
||||
cb->NoteXPCOMChild(aData.get());
|
||||
cb->NoteXPCOMChild(static_cast<nsINode*>(aData.get()));
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
@ -131,12 +131,11 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMAttributeMap)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMAttributeMap)
|
||||
|
||||
PLDHashOperator
|
||||
SetOwnerDocumentFunc(nsAttrHashKey::KeyType aKey, nsCOMPtr<nsIDOMNode>& aData,
|
||||
SetOwnerDocumentFunc(nsAttrHashKey::KeyType aKey,
|
||||
nsRefPtr<nsDOMAttribute>& aData,
|
||||
void* aUserArg)
|
||||
{
|
||||
nsCOMPtr<nsIAttribute> attr(do_QueryInterface(aData));
|
||||
NS_ASSERTION(attr, "non-nsIAttribute somehow made it into the hashmap?!");
|
||||
nsresult rv = attr->SetOwnerDocument(static_cast<nsIDocument*>(aUserArg));
|
||||
nsresult rv = aData->SetOwnerDocument(static_cast<nsIDocument*>(aUserArg));
|
||||
|
||||
return NS_FAILED(rv) ? PL_DHASH_STOP : PL_DHASH_NEXT;
|
||||
}
|
||||
@ -154,13 +153,10 @@ void
|
||||
nsDOMAttributeMap::DropAttribute(PRInt32 aNamespaceID, nsIAtom* aLocalName)
|
||||
{
|
||||
nsAttrKey attr(aNamespaceID, aLocalName);
|
||||
nsIDOMNode *node = mAttributeCache.GetWeak(attr);
|
||||
nsDOMAttribute *node = mAttributeCache.GetWeak(attr);
|
||||
if (node) {
|
||||
nsCOMPtr<nsIAttribute> iAttr(do_QueryInterface(node));
|
||||
NS_ASSERTION(iAttr, "non-nsIAttribute somehow made it into the hashmap?!");
|
||||
|
||||
// Break link to map
|
||||
iAttr->SetMap(nsnull);
|
||||
node->SetMap(nsnull);
|
||||
|
||||
// Remove from cache
|
||||
mAttributeCache.Remove(attr);
|
||||
@ -177,7 +173,8 @@ nsDOMAttributeMap::RemoveAttribute(nsINodeInfo* aNodeInfo, nsIDOMNode** aReturn)
|
||||
|
||||
nsAttrKey attr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom());
|
||||
|
||||
if (!mAttributeCache.Get(attr, aReturn)) {
|
||||
nsRefPtr<nsDOMAttribute> node;
|
||||
if (!mAttributeCache.Get(attr, getter_AddRefs(node))) {
|
||||
nsAutoString value;
|
||||
// As we are removing the attribute we need to set the current value in
|
||||
// the attribute node.
|
||||
@ -189,29 +186,28 @@ nsDOMAttributeMap::RemoveAttribute(nsINodeInfo* aNodeInfo, nsIDOMNode** aReturn)
|
||||
newAttr.swap(*aReturn);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIAttribute> iAttr(do_QueryInterface(*aReturn));
|
||||
NS_ASSERTION(iAttr, "non-nsIAttribute somehow made it into the hashmap?!");
|
||||
|
||||
// Break link to map
|
||||
iAttr->SetMap(nsnull);
|
||||
node->SetMap(nsnull);
|
||||
|
||||
// Remove from cache
|
||||
mAttributeCache.Remove(attr);
|
||||
|
||||
node.forget(aReturn);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIDOMNode*
|
||||
nsDOMAttribute*
|
||||
nsDOMAttributeMap::GetAttribute(nsINodeInfo* aNodeInfo)
|
||||
{
|
||||
NS_ASSERTION(aNodeInfo, "GetAttribute() called with aNodeInfo == nsnull!");
|
||||
|
||||
nsAttrKey attr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom());
|
||||
|
||||
nsIDOMNode* node = mAttributeCache.GetWeak(attr);
|
||||
nsDOMAttribute* node = mAttributeCache.GetWeak(attr);
|
||||
if (!node) {
|
||||
nsCOMPtr<nsIDOMNode> newAttr =
|
||||
nsRefPtr<nsDOMAttribute> newAttr =
|
||||
new nsDOMAttribute(this, aNodeInfo, EmptyString());
|
||||
if (newAttr && mAttributeCache.Put(attr, newAttr)) {
|
||||
node = newAttr;
|
||||
@ -221,7 +217,7 @@ nsDOMAttributeMap::GetAttribute(nsINodeInfo* aNodeInfo)
|
||||
return node;
|
||||
}
|
||||
|
||||
nsIDOMNode*
|
||||
nsDOMAttribute*
|
||||
nsDOMAttributeMap::GetNamedItem(const nsAString& aAttrName, nsresult *aResult)
|
||||
{
|
||||
*aResult = NS_OK;
|
||||
@ -230,12 +226,7 @@ nsDOMAttributeMap::GetNamedItem(const nsAString& aAttrName, nsresult *aResult)
|
||||
nsCOMPtr<nsINodeInfo> ni =
|
||||
mContent->GetExistingAttrNameFromQName(aAttrName);
|
||||
if (ni) {
|
||||
nsIDOMNode* node = GetAttribute(ni);
|
||||
if (node) {
|
||||
return node;
|
||||
}
|
||||
|
||||
*aResult = NS_ERROR_OUT_OF_MEMORY;
|
||||
return GetAttribute(ni);
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,12 +273,13 @@ nsDOMAttributeMap::SetNamedItemInternal(nsIDOMNode *aNode,
|
||||
// XXX should check same-origin between mContent and aNode however
|
||||
// nsContentUtils::CheckSameOrigin can't deal with attributenodes yet
|
||||
|
||||
nsCOMPtr<nsIDOMAttr> attribute(do_QueryInterface(aNode));
|
||||
nsCOMPtr<nsIAttribute> iAttribute(do_QueryInterface(aNode));
|
||||
if (!attribute || !iAttribute) {
|
||||
if (!iAttribute) {
|
||||
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
|
||||
}
|
||||
|
||||
nsDOMAttribute *attribute = static_cast<nsDOMAttribute*>(iAttribute.get());
|
||||
|
||||
// Check that attribute is not owned by somebody else
|
||||
nsDOMAttributeMap* owner = iAttribute->GetMap();
|
||||
if (owner) {
|
||||
@ -389,8 +381,7 @@ nsDOMAttributeMap::RemoveNamedItem(const nsAString& aName,
|
||||
return NS_ERROR_DOM_NOT_FOUND_ERR;
|
||||
}
|
||||
|
||||
rv = GetAttribute(ni, aReturn);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ADDREF(*aReturn = GetAttribute(ni));
|
||||
|
||||
// This removes the attribute node from the attribute map.
|
||||
rv = mContent->UnsetAttr(ni->NamespaceID(), ni->NameAtom(), PR_TRUE);
|
||||
@ -400,12 +391,12 @@ nsDOMAttributeMap::RemoveNamedItem(const nsAString& aName,
|
||||
}
|
||||
|
||||
|
||||
nsIDOMNode*
|
||||
nsDOMAttribute*
|
||||
nsDOMAttributeMap::GetItemAt(PRUint32 aIndex, nsresult *aResult)
|
||||
{
|
||||
*aResult = NS_OK;
|
||||
|
||||
nsIDOMNode* node = nsnull;
|
||||
nsDOMAttribute* node = nsnull;
|
||||
|
||||
const nsAttrName* name;
|
||||
if (mContent && (name = mContent->GetAttrNameAt(aIndex))) {
|
||||
@ -417,7 +408,7 @@ nsDOMAttributeMap::GetItemAt(PRUint32 aIndex, nsresult *aResult)
|
||||
if (ni) {
|
||||
node = GetAttribute(ni);
|
||||
}
|
||||
if (!node) {
|
||||
else {
|
||||
*aResult = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
@ -493,7 +484,13 @@ nsDOMAttributeMap::GetNamedItemNSInternal(const nsAString& aNamespaceURI,
|
||||
GetNodeInfo(nameAtom, name->GetPrefix(), nameSpaceID);
|
||||
NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return aRemove ? RemoveAttribute(ni, aReturn) : GetAttribute(ni, aReturn);
|
||||
if (aRemove) {
|
||||
return RemoveAttribute(ni, aReturn);
|
||||
}
|
||||
|
||||
NS_ADDREF(*aReturn = GetAttribute(ni));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@
|
||||
|
||||
#include "nsIDOMNamedNodeMap.h"
|
||||
#include "nsString.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsRefPtrHashtable.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "prbit.h"
|
||||
#include "nsIDOMNode.h"
|
||||
@ -160,7 +160,7 @@ public:
|
||||
*/
|
||||
PRUint32 Count() const;
|
||||
|
||||
typedef nsInterfaceHashtable<nsAttrHashKey, nsIDOMNode> AttrCache;
|
||||
typedef nsRefPtrHashtable<nsAttrHashKey, nsDOMAttribute> AttrCache;
|
||||
|
||||
/**
|
||||
* Enumerates over the attribute nodess in the map and calls aFunc for each
|
||||
@ -170,8 +170,8 @@ public:
|
||||
*/
|
||||
PRUint32 Enumerate(AttrCache::EnumReadFunction aFunc, void *aUserArg) const;
|
||||
|
||||
nsIDOMNode* GetItemAt(PRUint32 aIndex, nsresult *rv);
|
||||
nsIDOMNode* GetNamedItem(const nsAString& aAttrName, nsresult *rv);
|
||||
nsDOMAttribute* GetItemAt(PRUint32 aIndex, nsresult *rv);
|
||||
nsDOMAttribute* GetNamedItem(const nsAString& aAttrName, nsresult *rv);
|
||||
|
||||
static nsDOMAttributeMap* FromSupports(nsISupports* aSupports)
|
||||
{
|
||||
@ -217,24 +217,7 @@ private:
|
||||
nsIDOMNode** aReturn,
|
||||
PRBool aRemove = PR_FALSE);
|
||||
|
||||
/**
|
||||
* Returns an attribute, either by retrieving it from the cache or by
|
||||
* creating a new one.
|
||||
*/
|
||||
nsresult GetAttribute(nsINodeInfo* aNodeInfo,
|
||||
nsIDOMNode** aReturn)
|
||||
{
|
||||
*aReturn = GetAttribute(aNodeInfo);
|
||||
if (!*aReturn) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_ADDREF(*aReturn);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIDOMNode* GetAttribute(nsINodeInfo* aNodeInfo);
|
||||
nsDOMAttribute* GetAttribute(nsINodeInfo* aNodeInfo);
|
||||
|
||||
/**
|
||||
* Remove an attribute, returns the removed node.
|
||||
|
@ -5619,12 +5619,12 @@ nsDocument::SetDocumentURI(const nsAString& aDocumentURI)
|
||||
static void BlastSubtreeToPieces(nsINode *aNode);
|
||||
|
||||
PLDHashOperator
|
||||
BlastFunc(nsAttrHashKey::KeyType aKey, nsIDOMNode *aData, void* aUserArg)
|
||||
BlastFunc(nsAttrHashKey::KeyType aKey, nsDOMAttribute *aData, void* aUserArg)
|
||||
{
|
||||
nsCOMPtr<nsIAttribute> *attr =
|
||||
static_cast<nsCOMPtr<nsIAttribute>*>(aUserArg);
|
||||
|
||||
*attr = do_QueryInterface(aData);
|
||||
*attr = aData;
|
||||
|
||||
NS_ASSERTION(attr->get(),
|
||||
"non-nsIAttribute somehow made it into the hashmap?!");
|
||||
|
@ -203,6 +203,7 @@ GK_ATOM(classid, "classid")
|
||||
GK_ATOM(clear, "clear")
|
||||
GK_ATOM(click, "click")
|
||||
GK_ATOM(clickcount, "clickcount")
|
||||
GK_ATOM(clickthrough, "clickthrough")
|
||||
GK_ATOM(movetoclick, "movetoclick")
|
||||
GK_ATOM(clip, "clip")
|
||||
GK_ATOM(close, "close")
|
||||
|
@ -38,14 +38,13 @@
|
||||
#ifndef nsNodeUtils_h___
|
||||
#define nsNodeUtils_h___
|
||||
|
||||
#include "nsDOMAttributeMap.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsINode.h"
|
||||
|
||||
struct CharacterDataChangeInfo;
|
||||
struct JSContext;
|
||||
struct JSObject;
|
||||
class nsIVariant;
|
||||
class nsIDOMNode;
|
||||
class nsIDOMUserDataHandler;
|
||||
template<class E> class nsCOMArray;
|
||||
class nsCycleCollectionTraversalCallback;
|
||||
@ -250,9 +249,6 @@ public:
|
||||
static void UnlinkUserData(nsINode *aNode);
|
||||
|
||||
private:
|
||||
friend PLDHashOperator
|
||||
AdoptFunc(nsAttrHashKey::KeyType aKey, nsIDOMNode *aData, void* aUserArg);
|
||||
|
||||
/**
|
||||
* Walks aNode, its attributes and, if aDeep is PR_TRUE, its descendant nodes.
|
||||
* If aClone is PR_TRUE the nodes will be cloned. If aNewNodeInfoManager is
|
||||
|
@ -2703,6 +2703,27 @@ nsEventStateManager::DecideGestureEvent(nsGestureNotifyEvent* aEvent,
|
||||
aEvent->panDirection = panDirection;
|
||||
}
|
||||
|
||||
static bool
|
||||
NodeAllowsClickThrough(nsINode* aNode)
|
||||
{
|
||||
while (aNode) {
|
||||
if (aNode->IsElement() && aNode->AsElement()->IsXUL()) {
|
||||
mozilla::dom::Element* element = aNode->AsElement();
|
||||
static nsIContent::AttrValuesArray strings[] =
|
||||
{&nsGkAtoms::always, &nsGkAtoms::never, nsnull};
|
||||
switch (element->FindAttrValueIn(kNameSpaceID_None, nsGkAtoms::clickthrough,
|
||||
strings, eCaseMatters)) {
|
||||
case 0:
|
||||
return true;
|
||||
case 1:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
aNode = nsContentUtils::GetCrossDocParentNode(aNode);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
nsEvent *aEvent,
|
||||
@ -3166,6 +3187,19 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
SetContentState(targetContent, NS_EVENT_STATE_HOVER);
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
case NS_MOUSE_ACTIVATE:
|
||||
if (mCurrentTarget) {
|
||||
nsCOMPtr<nsIContent> targetContent;
|
||||
mCurrentTarget->GetContentForEvent(presContext, aEvent,
|
||||
getter_AddRefs(targetContent));
|
||||
if (!NodeAllowsClickThrough(targetContent)) {
|
||||
*aStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
//Reset target frame to null to avoid mistargeting after reentrant event
|
||||
|
@ -45,6 +45,12 @@ class nsString;
|
||||
class nsIFormProcessor;
|
||||
class nsFormSubmission;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Element;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
enum FormControlsTypes {
|
||||
NS_FORM_FIELDSET = 1,
|
||||
NS_FORM_LABEL,
|
||||
@ -93,8 +99,8 @@ PR_STATIC_ASSERT((PRUint32)eButtonElementTypesMax < (PRUint32)NS_FORM_INPUT_ELEM
|
||||
PR_STATIC_ASSERT((PRUint32)eInputElementTypesMax < 1<<8);
|
||||
|
||||
#define NS_IFORMCONTROL_IID \
|
||||
{ 0x52dc1f0d, 0x1683, 0x4dd7, \
|
||||
{ 0xae, 0x0a, 0xc4, 0x76, 0x10, 0x64, 0x2f, 0xa8 } }
|
||||
{ 0x0dc5083b, 0xb0a8, 0x48c4, \
|
||||
{ 0xb2, 0xeb, 0xc2, 0x4f, 0xfb, 0x7e, 0xc2, 0x8e } }
|
||||
|
||||
/**
|
||||
* Interface which all form controls (e.g. buttons, checkboxes, text,
|
||||
@ -109,9 +115,9 @@ public:
|
||||
|
||||
/**
|
||||
* Get the form for this form control.
|
||||
* @param aForm the form [OUT]
|
||||
* @return the form
|
||||
*/
|
||||
NS_IMETHOD GetForm(nsIDOMHTMLFormElement** aForm) = 0;
|
||||
virtual mozilla::dom::Element *GetFormElement() = 0;
|
||||
|
||||
/**
|
||||
* Set the form for this form control.
|
||||
|
@ -111,6 +111,9 @@
|
||||
#include "mozAutoDocUpdate.h"
|
||||
#include "nsHtml5Module.h"
|
||||
#include "nsITextControlElement.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
@ -2379,7 +2382,13 @@ nsGenericHTMLFormElement::ClearForm(PRBool aRemoveFromForm,
|
||||
mForm = nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Element*
|
||||
nsGenericHTMLFormElement::GetFormElement()
|
||||
{
|
||||
return mForm;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLFormElement::GetForm(nsIDOMHTMLFormElement** aForm)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aForm);
|
||||
|
@ -803,10 +803,12 @@ public:
|
||||
virtual void SaveSubtreeState();
|
||||
|
||||
// nsIFormControl
|
||||
NS_IMETHOD GetForm(nsIDOMHTMLFormElement** aForm);
|
||||
virtual mozilla::dom::Element* GetFormElement();
|
||||
virtual void SetForm(nsIDOMHTMLFormElement* aForm);
|
||||
virtual void ClearForm(PRBool aRemoveFromForm, PRBool aNotify);
|
||||
|
||||
nsresult GetForm(nsIDOMHTMLFormElement** aForm);
|
||||
|
||||
NS_IMETHOD SaveState()
|
||||
{
|
||||
return NS_OK;
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
|
||||
class nsFormControlList;
|
||||
|
||||
|
@ -35,10 +35,9 @@
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#include "nsIDOMHTMLLegendElement.h"
|
||||
#include "nsHTMLLegendElement.h"
|
||||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsIForm.h"
|
||||
@ -49,68 +48,6 @@
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsIFrame.h"
|
||||
|
||||
class nsHTMLLegendElement : public nsGenericHTMLElement,
|
||||
public nsIDOMHTMLLegendElement
|
||||
{
|
||||
public:
|
||||
nsHTMLLegendElement(nsINodeInfo *aNodeInfo);
|
||||
virtual ~nsHTMLLegendElement();
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIDOMNode
|
||||
NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMElement
|
||||
NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLElement
|
||||
NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLLegendElement
|
||||
NS_DECL_NSIDOMHTMLLEGENDELEMENT
|
||||
|
||||
// nsGenericHTMLElement
|
||||
NS_IMETHODIMP Focus();
|
||||
|
||||
virtual void PerformAccesskey(PRBool aKeyCausesActivation,
|
||||
PRBool aIsTrustedEvent);
|
||||
|
||||
// nsIContent
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||
PRInt32 aModType) const;
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
|
||||
}
|
||||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify);
|
||||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify);
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Get the fieldset content element that contains this legend.
|
||||
* Returns null if there is no fieldset containing this legend.
|
||||
*/
|
||||
nsIContent* GetFieldSet();
|
||||
};
|
||||
|
||||
|
||||
NS_IMPL_NS_NEW_HTML_ELEMENT(Legend)
|
||||
|
||||
|
||||
@ -147,11 +84,9 @@ NS_IMPL_ELEMENT_CLONE(nsHTMLLegendElement)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLegendElement::GetForm(nsIDOMHTMLFormElement** aForm)
|
||||
{
|
||||
*aForm = nsnull;
|
||||
Element *form = GetFormElement();
|
||||
|
||||
nsCOMPtr<nsIFormControl> fieldsetControl = do_QueryInterface(GetFieldSet());
|
||||
|
||||
return fieldsetControl ? fieldsetControl->GetForm(aForm) : NS_OK;
|
||||
return form ? CallQueryInterface(form, aForm) : NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
119
content/html/content/src/nsHTMLLegendElement.h
Normal file
119
content/html/content/src/nsHTMLLegendElement.h
Normal file
@ -0,0 +1,119 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Mats Palmgren <mats.palmgren@bredband.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#ifndef nsHTMLLegendElement_h___
|
||||
#define nsHTMLLegendElement_h___
|
||||
|
||||
#include "nsIDOMHTMLLegendElement.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
|
||||
class nsHTMLLegendElement : public nsGenericHTMLElement,
|
||||
public nsIDOMHTMLLegendElement
|
||||
{
|
||||
public:
|
||||
nsHTMLLegendElement(nsINodeInfo *aNodeInfo);
|
||||
virtual ~nsHTMLLegendElement();
|
||||
|
||||
static nsHTMLLegendElement* FromContent(nsIContent *aContent)
|
||||
{
|
||||
if (aContent->IsHTML() && aContent->Tag() == nsGkAtoms::legend)
|
||||
return static_cast<nsHTMLLegendElement*>(aContent);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIDOMNode
|
||||
NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMElement
|
||||
NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLElement
|
||||
NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLLegendElement
|
||||
NS_DECL_NSIDOMHTMLLEGENDELEMENT
|
||||
|
||||
// nsGenericHTMLElement
|
||||
NS_IMETHODIMP Focus();
|
||||
|
||||
virtual void PerformAccesskey(PRBool aKeyCausesActivation,
|
||||
PRBool aIsTrustedEvent);
|
||||
|
||||
// nsIContent
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
virtual PRBool ParseAttribute(PRInt32 aNamespaceID,
|
||||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||
PRInt32 aModType) const;
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
{
|
||||
return SetAttr(aNameSpaceID, aName, nsnull, aValue, aNotify);
|
||||
}
|
||||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify);
|
||||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify);
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
mozilla::dom::Element *GetFormElement()
|
||||
{
|
||||
nsCOMPtr<nsIFormControl> fieldsetControl = do_QueryInterface(GetFieldSet());
|
||||
|
||||
return fieldsetControl ? fieldsetControl->GetFormElement() : nsnull;
|
||||
}
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Get the fieldset content element that contains this legend.
|
||||
* Returns null if there is no fieldset containing this legend.
|
||||
*/
|
||||
nsIContent* GetFieldSet();
|
||||
};
|
||||
|
||||
#endif /* nsHTMLLegendElement_h___ */
|
@ -134,7 +134,8 @@ nsHTMLOptionElement::GetForm(nsIDOMHTMLFormElement** aForm)
|
||||
NS_ENSURE_ARG_POINTER(aForm);
|
||||
*aForm = nsnull;
|
||||
|
||||
nsCOMPtr<nsIFormControl> selectControl = do_QueryInterface(GetSelect());
|
||||
nsCOMPtr<nsIDOMHTMLSelectElement> selectControl =
|
||||
do_QueryInterface(GetSelect());
|
||||
|
||||
if (selectControl) {
|
||||
selectControl->GetForm(aForm);
|
||||
|
@ -1,112 +1,120 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 sw=2 et tw=78: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
* Mats Palmgren <mats.palmgren@bredband.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsHTMLOptionElement_h__
|
||||
#define nsHTMLOptionElement_h__
|
||||
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsIDOMHTMLOptionElement.h"
|
||||
#include "nsIDOMNSHTMLOptionElement.h"
|
||||
#include "nsIJSNativeInitializer.h"
|
||||
|
||||
class nsHTMLOptionElement : public nsGenericHTMLElement,
|
||||
public nsIDOMHTMLOptionElement,
|
||||
public nsIDOMNSHTMLOptionElement,
|
||||
public nsIJSNativeInitializer
|
||||
{
|
||||
public:
|
||||
nsHTMLOptionElement(nsINodeInfo *aNodeInfo);
|
||||
virtual ~nsHTMLOptionElement();
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIDOMNode
|
||||
NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMElement
|
||||
NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLElement
|
||||
NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLOptionElement
|
||||
NS_DECL_NSIDOMHTMLOPTIONELEMENT
|
||||
|
||||
// nsIDOMNSHTMLOptionElement
|
||||
NS_IMETHOD SetText(const nsAString & aText);
|
||||
|
||||
// nsIJSNativeInitializer
|
||||
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext,
|
||||
JSObject *aObj, PRUint32 argc, jsval *argv);
|
||||
|
||||
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||
PRInt32 aModType) const;
|
||||
|
||||
virtual nsresult BeforeSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
|
||||
void SetSelectedInternal(PRBool aValue, PRBool aNotify);
|
||||
|
||||
// nsIContent
|
||||
virtual PRInt32 IntrinsicState() const;
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
nsresult CopyInnerTo(nsGenericElement* aDest) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Get the select content element that contains this option, this
|
||||
* intentionally does not return nsresult, all we care about is if
|
||||
* there's a select associated with this option or not.
|
||||
* @param aSelectElement the select element (out param)
|
||||
*/
|
||||
nsIContent* GetSelect();
|
||||
|
||||
PRPackedBool mSelectedChanged;
|
||||
PRPackedBool mIsSelected;
|
||||
|
||||
// True only while we're under the SetOptionsSelectedByIndex call when our
|
||||
// "selected" attribute is changing and mSelectedChanged is false.
|
||||
PRPackedBool mIsInSetDefaultSelected;
|
||||
};
|
||||
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 sw=2 et tw=78: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||
* Mats Palmgren <mats.palmgren@bredband.net>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsHTMLOptionElement_h__
|
||||
#define nsHTMLOptionElement_h__
|
||||
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsIDOMHTMLOptionElement.h"
|
||||
#include "nsIDOMNSHTMLOptionElement.h"
|
||||
#include "nsIJSNativeInitializer.h"
|
||||
|
||||
class nsHTMLOptionElement : public nsGenericHTMLElement,
|
||||
public nsIDOMHTMLOptionElement,
|
||||
public nsIDOMNSHTMLOptionElement,
|
||||
public nsIJSNativeInitializer
|
||||
{
|
||||
public:
|
||||
nsHTMLOptionElement(nsINodeInfo *aNodeInfo);
|
||||
virtual ~nsHTMLOptionElement();
|
||||
|
||||
/** Typesafe, non-refcounting cast from nsIContent. Cheaper than QI. **/
|
||||
static nsHTMLOptionElement* FromContent(nsIContent *aContent)
|
||||
{
|
||||
if (aContent->NodeInfo()->Equals(nsGkAtoms::option, kNameSpaceID_XHTML))
|
||||
return static_cast<nsHTMLOptionElement*>(aContent);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// nsIDOMNode
|
||||
NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMElement
|
||||
NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLElement
|
||||
NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
|
||||
|
||||
// nsIDOMHTMLOptionElement
|
||||
NS_DECL_NSIDOMHTMLOPTIONELEMENT
|
||||
|
||||
// nsIDOMNSHTMLOptionElement
|
||||
NS_IMETHOD SetText(const nsAString & aText);
|
||||
|
||||
// nsIJSNativeInitializer
|
||||
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* aContext,
|
||||
JSObject *aObj, PRUint32 argc, jsval *argv);
|
||||
|
||||
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||
PRInt32 aModType) const;
|
||||
|
||||
virtual nsresult BeforeSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
|
||||
void SetSelectedInternal(PRBool aValue, PRBool aNotify);
|
||||
|
||||
// nsIContent
|
||||
virtual PRInt32 IntrinsicState() const;
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
nsresult CopyInnerTo(nsGenericElement* aDest) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Get the select content element that contains this option, this
|
||||
* intentionally does not return nsresult, all we care about is if
|
||||
* there's a select associated with this option or not.
|
||||
* @param aSelectElement the select element (out param)
|
||||
*/
|
||||
nsIContent* GetSelect();
|
||||
|
||||
PRPackedBool mSelectedChanged;
|
||||
PRPackedBool mIsSelected;
|
||||
|
||||
// True only while we're under the SetOptionsSelectedByIndex call when our
|
||||
// "selected" attribute is changing and mSelectedChanged is false.
|
||||
PRPackedBool mIsInSetDefaultSelected;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -38,6 +38,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsHTMLSelectElement.h"
|
||||
#include "nsHTMLOptionElement.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsGkAtoms.h"
|
||||
@ -69,6 +70,9 @@
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsRuleData.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsSelectState, nsSelectState)
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsSelectState, NS_SELECT_STATE_IID)
|
||||
@ -351,7 +355,7 @@ nsHTMLSelectElement::InsertOptionsIntoListRecurse(nsIContent* aOptions,
|
||||
// just not going to look for an option inside of an option.
|
||||
// Sue me.
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLOptionElement> optElement(do_QueryInterface(aOptions));
|
||||
nsHTMLOptionElement *optElement = nsHTMLOptionElement::FromContent(aOptions);
|
||||
if (optElement) {
|
||||
nsresult rv = mOptions->InsertOptionAt(optElement, *aInsertIndex);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -569,7 +573,7 @@ PRInt32
|
||||
nsHTMLSelectElement::GetFirstOptionIndex(nsIContent* aOptions)
|
||||
{
|
||||
PRInt32 listIndex = -1;
|
||||
nsCOMPtr<nsIDOMHTMLOptionElement> optElement(do_QueryInterface(aOptions));
|
||||
nsHTMLOptionElement *optElement = nsHTMLOptionElement::FromContent(aOptions);
|
||||
if (optElement) {
|
||||
GetOptionIndex(optElement, 0, PR_TRUE, &listIndex);
|
||||
// If you nested stuff under the option, you're just plain
|
||||
@ -671,8 +675,7 @@ nsHTMLSelectElement::Remove(PRInt32 aIndex)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLSelectElement::GetOptions(nsIDOMHTMLOptionsCollection** aValue)
|
||||
{
|
||||
*aValue = mOptions;
|
||||
NS_IF_ADDREF(*aValue);
|
||||
NS_IF_ADDREF(*aValue = GetOptions());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -795,7 +798,8 @@ nsHTMLSelectElement::GetOptionIndex(nsIDOMHTMLOptionElement* aOption,
|
||||
PRInt32 aStartIndex, PRBool aForward,
|
||||
PRInt32* aIndex)
|
||||
{
|
||||
return mOptions->GetOptionIndex(aOption, aStartIndex, aForward, aIndex);
|
||||
nsCOMPtr<Element> option = do_QueryInterface(aOption);
|
||||
return mOptions->GetOptionIndex(option, aStartIndex, aForward, aIndex);
|
||||
}
|
||||
|
||||
PRBool
|
||||
@ -1700,7 +1704,7 @@ AddOptionsRecurse(nsIContent* aRoot, nsHTMLOptionCollection* aArray)
|
||||
{
|
||||
nsIContent* child;
|
||||
for(PRUint32 i = 0; (child = aRoot->GetChildAt(i)); ++i) {
|
||||
nsCOMPtr<nsIDOMHTMLOptionElement> opt = do_QueryInterface(child);
|
||||
nsHTMLOptionElement *opt = nsHTMLOptionElement::FromContent(child);
|
||||
if (opt) {
|
||||
// If we fail here, then at least we've tried our best
|
||||
aArray->AppendOption(opt);
|
||||
@ -1773,7 +1777,7 @@ nsHTMLOptionCollection::DropReference()
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLOptionCollection::GetOptionIndex(nsIDOMHTMLOptionElement* aOption,
|
||||
nsHTMLOptionCollection::GetOptionIndex(mozilla::dom::Element* aOption,
|
||||
PRInt32 aStartIndex,
|
||||
PRBool aForward,
|
||||
PRInt32* aIndex)
|
||||
@ -1791,7 +1795,7 @@ nsHTMLOptionCollection::GetOptionIndex(nsIDOMHTMLOptionElement* aOption,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32 high = mElements.Count();
|
||||
PRInt32 high = mElements.Length();
|
||||
PRInt32 step = aForward ? 1 : -1;
|
||||
|
||||
for (index = aStartIndex; index < high && index > -1; index += step) {
|
||||
@ -1807,10 +1811,16 @@ nsHTMLOptionCollection::GetOptionIndex(nsIDOMHTMLOptionElement* aOption,
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLOptionCollection)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsHTMLOptionCollection)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mElements)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mElements)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsHTMLOptionCollection)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mElements)
|
||||
{
|
||||
PRUint32 i;
|
||||
for (i = 0; i < tmp->mElements.Length(); ++i) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mElements[i]");
|
||||
cb.NoteXPCOMChild(static_cast<Element*>(tmp->mElements[i]));
|
||||
}
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
// nsISupports
|
||||
@ -1840,7 +1850,7 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsHTMLOptionCollection,
|
||||
NS_IMETHODIMP
|
||||
nsHTMLOptionCollection::GetLength(PRUint32* aLength)
|
||||
{
|
||||
*aLength = mElements.Count();
|
||||
*aLength = mElements.Length();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1862,7 +1872,7 @@ nsHTMLOptionCollection::SetOption(PRInt32 aIndex,
|
||||
if (aIndex < 0 || !mSelect) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
// if the new option is null, just remove this option. Note that it's safe
|
||||
// to pass a too-large aIndex in here.
|
||||
if (!aOption) {
|
||||
@ -1874,23 +1884,25 @@ nsHTMLOptionCollection::SetOption(PRInt32 aIndex,
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRUint32 index = PRUint32(aIndex);
|
||||
|
||||
// Now we're going to be setting an option in our collection
|
||||
if (aIndex > mElements.Count()) {
|
||||
if (index > mElements.Length()) {
|
||||
// Fill our array with blank options up to (but not including, since we're
|
||||
// about to change it) aIndex, for compat with other browsers.
|
||||
rv = SetLength(aIndex);
|
||||
rv = SetLength(index);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
NS_ASSERTION(aIndex <= mElements.Count(), "SetLength lied");
|
||||
NS_ASSERTION(index <= mElements.Length(), "SetLength lied");
|
||||
|
||||
nsCOMPtr<nsIDOMNode> ret;
|
||||
if (aIndex == mElements.Count()) {
|
||||
if (index == mElements.Length()) {
|
||||
rv = mSelect->AppendChild(aOption, getter_AddRefs(ret));
|
||||
} else {
|
||||
// Find the option they're talking about and replace it
|
||||
// hold a strong reference to follow COM rules.
|
||||
nsCOMPtr<nsIDOMHTMLOptionElement> refChild = mElements.SafeObjectAt(aIndex);
|
||||
nsCOMPtr<nsIDOMHTMLOptionElement> refChild = ItemAsOption(index);
|
||||
NS_ENSURE_TRUE(refChild, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsCOMPtr<nsIDOMNode> parent;
|
||||
@ -1933,14 +1945,22 @@ nsHTMLOptionCollection::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
|
||||
return CallQueryInterface(item, aReturn);
|
||||
}
|
||||
|
||||
nsISupports*
|
||||
nsHTMLOptionCollection::GetNodeAt(PRUint32 aIndex, nsresult* aResult)
|
||||
{
|
||||
*aResult = NS_OK;
|
||||
|
||||
return static_cast<Element*>(ItemAsOption(aIndex));
|
||||
}
|
||||
|
||||
nsISupports*
|
||||
nsHTMLOptionCollection::GetNamedItem(const nsAString& aName, nsresult* aResult)
|
||||
{
|
||||
*aResult = NS_OK;
|
||||
|
||||
PRInt32 count = mElements.Count();
|
||||
for (PRInt32 i = 0; i < count; i++) {
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mElements.ObjectAt(i));
|
||||
PRUint32 count = mElements.Length();
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
nsIContent *content = ItemAsOption(i);
|
||||
if (content &&
|
||||
(content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name, aName,
|
||||
eCaseMatters) ||
|
||||
|
@ -60,7 +60,7 @@
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsCheapSets.h"
|
||||
#include "nsLayoutErrors.h"
|
||||
|
||||
#include "nsHTMLOptionElement.h"
|
||||
|
||||
class nsHTMLSelectElement;
|
||||
|
||||
@ -87,12 +87,7 @@ public:
|
||||
// nsIDOMHTMLCollection interface, all its methods are defined in
|
||||
// nsIDOMHTMLOptionsCollection
|
||||
|
||||
virtual nsISupports* GetNodeAt(PRUint32 aIndex, nsresult* aResult)
|
||||
{
|
||||
*aResult = NS_OK;
|
||||
|
||||
return mElements.SafeObjectAt(aIndex);
|
||||
}
|
||||
virtual nsISupports* GetNodeAt(PRUint32 aIndex, nsresult* aResult);
|
||||
virtual nsISupports* GetNamedItem(const nsAString& aName, nsresult* aResult);
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsHTMLOptionCollection,
|
||||
@ -104,18 +99,18 @@ public:
|
||||
* @param aOption the option to insert
|
||||
* @param aIndex the index to insert at
|
||||
*/
|
||||
PRBool InsertOptionAt(nsIDOMHTMLOptionElement* aOption, PRInt32 aIndex)
|
||||
PRBool InsertOptionAt(nsHTMLOptionElement* aOption, PRUint32 aIndex)
|
||||
{
|
||||
return mElements.InsertObjectAt(aOption, aIndex);
|
||||
return !!mElements.InsertElementAt(aIndex, aOption);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an option
|
||||
* @param aIndex the index of the option to remove
|
||||
*/
|
||||
void RemoveOptionAt(PRInt32 aIndex)
|
||||
void RemoveOptionAt(PRUint32 aIndex)
|
||||
{
|
||||
mElements.RemoveObjectAt(aIndex);
|
||||
mElements.RemoveElementAt(aIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,9 +118,9 @@ public:
|
||||
* @param aIndex the index
|
||||
* @param aReturn the option returned [OUT]
|
||||
*/
|
||||
nsIDOMHTMLOptionElement *ItemAsOption(PRInt32 aIndex)
|
||||
nsHTMLOptionElement *ItemAsOption(PRUint32 aIndex)
|
||||
{
|
||||
return mElements.SafeObjectAt(aIndex);
|
||||
return mElements.SafeElementAt(aIndex, nsRefPtr<nsHTMLOptionElement>());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,9 +134,9 @@ public:
|
||||
/**
|
||||
* Append an option to end of array
|
||||
*/
|
||||
PRBool AppendOption(nsIDOMHTMLOptionElement* aOption)
|
||||
PRBool AppendOption(nsHTMLOptionElement* aOption)
|
||||
{
|
||||
return mElements.AppendObject(aOption);
|
||||
return !!mElements.AppendElement(aOption);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -152,13 +147,13 @@ public:
|
||||
/**
|
||||
* See nsISelectElement.idl for documentation on this method
|
||||
*/
|
||||
nsresult GetOptionIndex(nsIDOMHTMLOptionElement* aOption,
|
||||
nsresult GetOptionIndex(mozilla::dom::Element* aOption,
|
||||
PRInt32 aStartIndex, PRBool aForward,
|
||||
PRInt32* aIndex);
|
||||
|
||||
private:
|
||||
/** The list of options (holds strong references) */
|
||||
nsCOMArray<nsIDOMHTMLOptionElement> mElements;
|
||||
nsTArray<nsRefPtr<nsHTMLOptionElement> > mElements;
|
||||
/** The select element that contains this array */
|
||||
nsHTMLSelectElement* mSelect;
|
||||
};
|
||||
@ -309,6 +304,16 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLSelectElement,
|
||||
nsGenericHTMLFormElement)
|
||||
|
||||
nsHTMLOptionCollection *GetOptions()
|
||||
{
|
||||
return mOptions;
|
||||
}
|
||||
|
||||
static nsHTMLSelectElement *FromSupports(nsISupports *aSupports)
|
||||
{
|
||||
return static_cast<nsHTMLSelectElement*>(static_cast<nsINode*>(aSupports));
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class nsSafeOptionListMutation;
|
||||
|
||||
|
@ -214,7 +214,7 @@
|
||||
#include "nsIDOMDOMImplementation.h"
|
||||
#include "nsIDOMDocumentFragment.h"
|
||||
#include "nsIDOMDocumentEvent.h"
|
||||
#include "nsIDOMAttr.h"
|
||||
#include "nsDOMAttribute.h"
|
||||
#include "nsIDOMText.h"
|
||||
#include "nsIDOM3Text.h"
|
||||
#include "nsIDOMComment.h"
|
||||
@ -476,6 +476,8 @@
|
||||
#include "nsIEventListenerService.h"
|
||||
#include "nsIFrameMessageManager.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsHTMLSelectElement.h"
|
||||
#include "nsHTMLLegendElement.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
@ -7474,9 +7476,8 @@ nsNodeSH::PreCreate(nsISupports *nativeObj, JSContext *cx, JSObject *globalObj,
|
||||
hasHadScriptHandlingObject ||
|
||||
IsPrivilegedScript());
|
||||
|
||||
nsISupports *native_parent;
|
||||
nsINode *native_parent;
|
||||
|
||||
PRBool slimWrappers = PR_TRUE;
|
||||
PRBool nodeIsElement = node->IsElement();
|
||||
if (nodeIsElement && node->AsElement()->IsXUL()) {
|
||||
// For XUL elements, use the parent, if any.
|
||||
@ -7499,23 +7500,21 @@ nsNodeSH::PreCreate(nsISupports *nativeObj, JSContext *cx, JSObject *globalObj,
|
||||
nsCOMPtr<nsIFormControl> form_control(do_QueryInterface(node));
|
||||
|
||||
if (form_control) {
|
||||
nsCOMPtr<nsIDOMHTMLFormElement> form;
|
||||
form_control->GetForm(getter_AddRefs(form));
|
||||
Element *form = form_control->GetFormElement();
|
||||
|
||||
if (form) {
|
||||
// Found a form, use it.
|
||||
native_parent = form;
|
||||
}
|
||||
}
|
||||
// Legend isn't an HTML form control but should have its fieldset form
|
||||
// as scope parent at least for backward compatibility.
|
||||
} else if (node->AsElement()->IsHTML() &&
|
||||
node->AsElement()->Tag() == nsGkAtoms::legend) {
|
||||
nsCOMPtr<nsIDOMHTMLLegendElement> legend(do_QueryInterface(node));
|
||||
|
||||
}
|
||||
else {
|
||||
// Legend isn't an HTML form control but should have its fieldset form
|
||||
// as scope parent at least for backward compatibility.
|
||||
nsHTMLLegendElement *legend =
|
||||
nsHTMLLegendElement::FromContent(node->AsElement());
|
||||
if (legend) {
|
||||
nsCOMPtr<nsIDOMHTMLFormElement> form;
|
||||
legend->GetForm(getter_AddRefs(form));
|
||||
Element *form = legend->GetFormElement();
|
||||
|
||||
if (form) {
|
||||
native_parent = form;
|
||||
@ -7528,19 +7527,27 @@ nsNodeSH::PreCreate(nsISupports *nativeObj, JSContext *cx, JSObject *globalObj,
|
||||
// document's global object, if there is one
|
||||
|
||||
// Get the scope object from the document.
|
||||
native_parent = doc->GetScopeObject();
|
||||
nsISupports *scope = doc->GetScopeObject();
|
||||
|
||||
if (!native_parent) {
|
||||
if (scope) {
|
||||
jsval v;
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||
nsresult rv = WrapNative(cx, globalObj, scope, nsnull, PR_FALSE, &v,
|
||||
getter_AddRefs(holder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
holder->GetJSObject(parentObj);
|
||||
}
|
||||
else {
|
||||
// No global object reachable from this document, use the
|
||||
// global object that was passed to this method.
|
||||
|
||||
*parentObj = globalObj;
|
||||
|
||||
return node->IsInNativeAnonymousSubtree() ?
|
||||
NS_SUCCESS_CHROME_ACCESS_ONLY : NS_OK;
|
||||
}
|
||||
|
||||
slimWrappers = PR_FALSE;
|
||||
// No slim wrappers for a document's scope object.
|
||||
return node->IsInNativeAnonymousSubtree() ?
|
||||
NS_SUCCESS_CHROME_ACCESS_ONLY : NS_OK;
|
||||
}
|
||||
|
||||
// XXXjst: Maybe we need to find the global to use from the
|
||||
@ -7548,22 +7555,12 @@ nsNodeSH::PreCreate(nsISupports *nativeObj, JSContext *cx, JSObject *globalObj,
|
||||
// to wrap here? But that's not always reachable, let's use
|
||||
// globalObj for now...
|
||||
|
||||
if (native_parent == doc && (*parentObj = doc->GetWrapper()))
|
||||
return node->IsInNativeAnonymousSubtree() ?
|
||||
NS_SUCCESS_CHROME_ACCESS_ONLY :
|
||||
(slimWrappers ? NS_SUCCESS_ALLOW_SLIM_WRAPPERS : NS_OK);
|
||||
|
||||
jsval v;
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
|
||||
nsresult rv = WrapNative(cx, globalObj, native_parent, PR_FALSE, &v,
|
||||
getter_AddRefs(holder));
|
||||
nsresult rv = WrapNativeParent(cx, globalObj, native_parent, native_parent,
|
||||
parentObj);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*parentObj = JSVAL_TO_OBJECT(v);
|
||||
|
||||
return node->IsInNativeAnonymousSubtree() ?
|
||||
NS_SUCCESS_CHROME_ACCESS_ONLY :
|
||||
(slimWrappers ? NS_SUCCESS_ALLOW_SLIM_WRAPPERS : NS_OK);
|
||||
NS_SUCCESS_CHROME_ACCESS_ONLY : NS_SUCCESS_ALLOW_SLIM_WRAPPERS;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -8361,7 +8358,8 @@ nsNamedNodeMapSH::GetItemAt(nsISupports *aNative, PRUint32 aIndex,
|
||||
{
|
||||
nsDOMAttributeMap* map = nsDOMAttributeMap::FromSupports(aNative);
|
||||
|
||||
return map->GetItemAt(aIndex, aResult);
|
||||
nsINode *attr = map->GetItemAt(aIndex, aResult);
|
||||
return attr;
|
||||
}
|
||||
|
||||
nsISupports*
|
||||
@ -8370,7 +8368,8 @@ nsNamedNodeMapSH::GetNamedItem(nsISupports *aNative, const nsAString& aName,
|
||||
{
|
||||
nsDOMAttributeMap* map = nsDOMAttributeMap::FromSupports(aNative);
|
||||
|
||||
return map->GetNamedItem(aName, aResult);
|
||||
nsINode *attr = map->GetNamedItem(aName, aResult);
|
||||
return attr;
|
||||
}
|
||||
|
||||
|
||||
@ -9525,15 +9524,13 @@ nsHTMLSelectElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper,
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
if (n >= 0) {
|
||||
nsCOMPtr<nsIDOMHTMLSelectElement> s = do_QueryWrappedNative(wrapper, obj);
|
||||
nsHTMLSelectElement *s =
|
||||
nsHTMLSelectElement::FromSupports(GetNative(wrapper, obj));
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLOptionsCollection> options;
|
||||
s->GetOptions(getter_AddRefs(options));
|
||||
nsHTMLOptionCollection *options = s->GetOptions();
|
||||
|
||||
if (options) {
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
|
||||
options->Item(n, getter_AddRefs(node));
|
||||
nsISupports *node = options->GetNodeAt(n, &rv);
|
||||
|
||||
rv = WrapNative(cx, obj, node, &NS_GET_IID(nsIDOMNode), PR_TRUE, vp);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -2198,6 +2198,8 @@ nsGfxScrollFrameInner::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mHScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::orient,
|
||||
NS_LITERAL_STRING("horizontal"), PR_FALSE);
|
||||
mHScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::clickthrough,
|
||||
NS_LITERAL_STRING("always"), PR_FALSE);
|
||||
if (!aElements.AppendElement(mHScrollbarContent))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -2208,6 +2210,8 @@ nsGfxScrollFrameInner::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mVScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::orient,
|
||||
NS_LITERAL_STRING("vertical"), PR_FALSE);
|
||||
mVScrollbarContent->SetAttr(kNameSpaceID_None, nsGkAtoms::clickthrough,
|
||||
NS_LITERAL_STRING("always"), PR_FALSE);
|
||||
if (!aElements.AppendElement(mVScrollbarContent))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -2243,6 +2247,8 @@ nsGfxScrollFrameInner::CreateAnonymousContent(nsTArray<nsIContent*>& aElements)
|
||||
mScrollCornerContent->SetAttr(kNameSpaceID_None, nsGkAtoms::dir, dir, PR_FALSE);
|
||||
mScrollCornerContent->SetAttr(kNameSpaceID_None, nsGkAtoms::element,
|
||||
NS_LITERAL_STRING("_parent"), PR_FALSE);
|
||||
mScrollCornerContent->SetAttr(kNameSpaceID_None, nsGkAtoms::clickthrough,
|
||||
NS_LITERAL_STRING("always"), PR_FALSE);
|
||||
|
||||
if (!aElements.AppendElement(mScrollCornerContent))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -51,6 +51,9 @@
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<binding id="browser" extends="xul:browser">
|
||||
<content clickthrough="never">
|
||||
<children/>
|
||||
</content>
|
||||
<implementation type="application/javascript" implements="nsIAccessibleProvider, nsIObserver, nsIDOMEventListener">
|
||||
<property name="accessibleType" readonly="true">
|
||||
<getter>
|
||||
|
@ -17,7 +17,7 @@
|
||||
</binding>
|
||||
|
||||
<binding id="scrollbar" extends="chrome://global/content/bindings/scrollbar.xml#scrollbar-base">
|
||||
<content>
|
||||
<content allowclickthrough="always">
|
||||
<xul:scrollbarbutton sbattr="scrollbar-up-top" type="decrement" xbl:inherits="curpos,maxpos,disabled,sborient=orient"/>
|
||||
<xul:scrollbarbutton sbattr="scrollbar-down-top" type="increment" xbl:inherits="curpos,maxpos,disabled,sborient=orient"/>
|
||||
<xul:slider flex="1" xbl:inherits="disabled,curpos,maxpos,pageincrement,increment,orient,sborient=orient">
|
||||
|
@ -30,7 +30,7 @@
|
||||
</binding>
|
||||
|
||||
<binding id="tree" extends="chrome://global/content/bindings/tree.xml#tree-base">
|
||||
<content hidevscroll="true" hidehscroll="true">
|
||||
<content hidevscroll="true" hidehscroll="true" clickthrough="never">
|
||||
<children includes="treecols"/>
|
||||
<xul:stack class="tree-stack" flex="1">
|
||||
<xul:treerows class="tree-rows" flex="1" xbl:inherits="hidevscroll">
|
||||
|
@ -143,7 +143,13 @@ extern "C" long TSMProcessRawKeyEvent(EventRef carbonEvent);
|
||||
|
||||
// when mouseDown: is called, we store its event here (strong)
|
||||
NSEvent* mLastMouseDownEvent;
|
||||
|
||||
|
||||
// Whether the last mouse down event was blocked from Gecko.
|
||||
BOOL mBlockedLastMouseDown;
|
||||
|
||||
// when acceptsFirstMouse: is called, we store the event here (strong)
|
||||
NSEvent* mClickThroughMouseDownEvent;
|
||||
|
||||
// rects that were invalidated during a draw, so have pending drawing
|
||||
NSMutableArray* mPendingDirtyRects;
|
||||
BOOL mPendingFullDisplay;
|
||||
@ -242,7 +248,8 @@ public:
|
||||
|
||||
static void MouseMoved(NSEvent* aEvent);
|
||||
static void OnDestroyView(ChildView* aView);
|
||||
static BOOL WindowAcceptsEvent(NSWindow* aWindow, NSEvent* aEvent);
|
||||
static BOOL WindowAcceptsEvent(NSWindow* aWindow, NSEvent* aEvent,
|
||||
ChildView* aView, BOOL isClickThrough = NO);
|
||||
static void ReEvaluateMouseEnterState(NSEvent* aEvent = nil);
|
||||
static ChildView* ViewForEvent(NSEvent* aEvent);
|
||||
|
||||
|
@ -204,6 +204,8 @@ PRUint32 nsChildView::sLastInputEventCount = 0;
|
||||
|
||||
- (void)fireKeyEventForFlagsChanged:(NSEvent*)theEvent keyDown:(BOOL)isKeyDown;
|
||||
|
||||
- (BOOL)inactiveWindowAcceptsMouseEvent:(NSEvent*)aEvent;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
@ -2206,12 +2208,14 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
||||
mKeyPressHandled = NO;
|
||||
mKeyPressSent = NO;
|
||||
mPendingDisplay = NO;
|
||||
mBlockedLastMouseDown = NO;
|
||||
|
||||
// initialization for NSTextInput
|
||||
mMarkedRange.location = NSNotFound;
|
||||
mMarkedRange.length = 0;
|
||||
|
||||
mLastMouseDownEvent = nil;
|
||||
mClickThroughMouseDownEvent = nil;
|
||||
mDragService = nsnull;
|
||||
|
||||
#ifndef NP_NO_CARBON
|
||||
@ -2276,6 +2280,7 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
||||
[mGLContext release];
|
||||
[mPendingDirtyRects release];
|
||||
[mLastMouseDownEvent release];
|
||||
[mClickThroughMouseDownEvent release];
|
||||
ChildViewMouseTracker::OnDestroyView(self);
|
||||
#ifndef NP_NO_CARBON
|
||||
if (mPluginTSMDoc)
|
||||
@ -2485,6 +2490,20 @@ NSEvent* gLastDragMouseDownEvent = nil;
|
||||
return YES;
|
||||
}
|
||||
|
||||
// Accept mouse down events on background windows
|
||||
- (BOOL)acceptsFirstMouse:(NSEvent*)aEvent
|
||||
{
|
||||
if (![[self window] isKindOfClass:[PopupWindow class]]) {
|
||||
// We rely on this function to tell us that the mousedown was on a
|
||||
// background window. Inside mouseDown we can't tell whether we were
|
||||
// inactive because at that point we've already been made active.
|
||||
// Unfortunately, acceptsFirstMouse is called for PopupWindows even when
|
||||
// their parent window is active, so ignore this on them for now.
|
||||
mClickThroughMouseDownEvent = [aEvent retain];
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)viewWillMoveToWindow:(NSWindow *)newWindow
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
@ -3094,9 +3113,9 @@ static BOOL DrawingAtWindowTop(CGContextRef aContext)
|
||||
if (![[self window] isKindOfClass:[PopupWindow class]])
|
||||
return NO;
|
||||
|
||||
// Don't reorder when we're already accepting mouse events, for example
|
||||
// because we're a context menu.
|
||||
return ChildViewMouseTracker::WindowAcceptsEvent([self window], aEvent);
|
||||
// Don't reorder when we don't have a parent window, like when we're a
|
||||
// context menu or a tooltip.
|
||||
return ![[self window] parentWindow];
|
||||
}
|
||||
|
||||
- (void)mouseDown:(NSEvent*)theEvent
|
||||
@ -3122,11 +3141,21 @@ static BOOL DrawingAtWindowTop(CGContextRef aContext)
|
||||
[gLastDragMouseDownEvent release];
|
||||
gLastDragMouseDownEvent = [theEvent retain];
|
||||
|
||||
// We need isClickThrough because at this point the window we're in might
|
||||
// already have become main, so the check for isMainWindow in
|
||||
// WindowAcceptsEvent isn't enough. It also has to check isClickThrough.
|
||||
BOOL isClickThrough = (theEvent == mClickThroughMouseDownEvent);
|
||||
[mClickThroughMouseDownEvent release];
|
||||
mClickThroughMouseDownEvent = nil;
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
||||
if ([self maybeRollup:theEvent] ||
|
||||
!ChildViewMouseTracker::WindowAcceptsEvent([self window], theEvent))
|
||||
!ChildViewMouseTracker::WindowAcceptsEvent([self window], theEvent, self, isClickThrough)) {
|
||||
// Remember blocking because that means we want to block mouseup as well.
|
||||
mBlockedLastMouseDown = YES;
|
||||
return;
|
||||
}
|
||||
|
||||
#if USE_CLICK_HOLD_CONTEXTMENU
|
||||
// fire off timer to check for click-hold after two seconds. retains |theEvent|
|
||||
@ -3141,7 +3170,15 @@ static BOOL DrawingAtWindowTop(CGContextRef aContext)
|
||||
|
||||
nsMouseEvent geckoEvent(PR_TRUE, NS_MOUSE_BUTTON_DOWN, nsnull, nsMouseEvent::eReal);
|
||||
[self convertCocoaMouseEvent:theEvent toGeckoEvent:&geckoEvent];
|
||||
geckoEvent.clickCount = [theEvent clickCount];
|
||||
|
||||
NSInteger clickCount = [theEvent clickCount];
|
||||
if (mBlockedLastMouseDown && clickCount > 1) {
|
||||
// Don't send a double click if the first click of the double click was
|
||||
// blocked.
|
||||
clickCount--;
|
||||
}
|
||||
geckoEvent.clickCount = clickCount;
|
||||
|
||||
if (modifierFlags & NSControlKeyMask)
|
||||
geckoEvent.button = nsMouseEvent::eRightButton;
|
||||
else
|
||||
@ -3170,7 +3207,7 @@ static BOOL DrawingAtWindowTop(CGContextRef aContext)
|
||||
cocoaEvent.data.mouse.pluginX = point.x;
|
||||
cocoaEvent.data.mouse.pluginY = point.y;
|
||||
cocoaEvent.data.mouse.buttonNumber = [theEvent buttonNumber];
|
||||
cocoaEvent.data.mouse.clickCount = [theEvent clickCount];
|
||||
cocoaEvent.data.mouse.clickCount = clickCount;
|
||||
cocoaEvent.data.mouse.deltaX = [theEvent deltaX];
|
||||
cocoaEvent.data.mouse.deltaY = [theEvent deltaY];
|
||||
cocoaEvent.data.mouse.deltaZ = [theEvent deltaZ];
|
||||
@ -3178,6 +3215,7 @@ static BOOL DrawingAtWindowTop(CGContextRef aContext)
|
||||
}
|
||||
|
||||
mGeckoChild->DispatchWindowEvent(geckoEvent);
|
||||
mBlockedLastMouseDown = NO;
|
||||
|
||||
// XXX maybe call markedTextSelectionChanged:client: here?
|
||||
|
||||
@ -3188,7 +3226,7 @@ static BOOL DrawingAtWindowTop(CGContextRef aContext)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (!mGeckoChild)
|
||||
if (!mGeckoChild || mBlockedLastMouseDown)
|
||||
return;
|
||||
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
@ -3550,7 +3588,7 @@ static BOOL DrawingAtWindowTop(CGContextRef aContext)
|
||||
nsAutoRetainCocoaObject kungFuDeathGrip(self);
|
||||
|
||||
if ([self maybeRollup:theEvent] ||
|
||||
!ChildViewMouseTracker::WindowAcceptsEvent([self window], theEvent))
|
||||
!ChildViewMouseTracker::WindowAcceptsEvent([self window], theEvent, self))
|
||||
return;
|
||||
|
||||
if (!mGeckoChild)
|
||||
@ -4180,8 +4218,8 @@ static PRBool IsNormalCharInputtingEvent(const nsKeyEvent& aEvent)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
NS_ASSERTION(aMouseEvent && outGeckoEvent, "convertCocoaMouseEvent:toGeckoEvent: requires non-null arguments");
|
||||
if (!aMouseEvent || !outGeckoEvent)
|
||||
NS_ASSERTION(outGeckoEvent, "convertCocoaMouseEvent:toGeckoEvent: requires non-null aoutGeckoEvent");
|
||||
if (!outGeckoEvent)
|
||||
return;
|
||||
|
||||
[self convertGenericCocoaEvent:aMouseEvent toGeckoEvent:outGeckoEvent];
|
||||
@ -5659,6 +5697,13 @@ static const char* ToEscapedString(NSString* aString, nsCAutoString& aBuf)
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (BOOL)inactiveWindowAcceptsMouseEvent:(NSEvent*)aEvent
|
||||
{
|
||||
nsMouseEvent geckoEvent(PR_TRUE, NS_MOUSE_ACTIVATE, nsnull, nsMouseEvent::eReal);
|
||||
[self convertCocoaMouseEvent:aEvent toGeckoEvent:&geckoEvent];
|
||||
return !mGeckoChild->DispatchWindowEvent(geckoEvent);
|
||||
}
|
||||
|
||||
- (void)updateCocoaPluginFocusStatus:(BOOL)hasFocus
|
||||
{
|
||||
if (!mGeckoChild)
|
||||
@ -6361,13 +6406,17 @@ ChildView*
|
||||
ChildViewMouseTracker::ViewForEvent(NSEvent* aEvent)
|
||||
{
|
||||
NSWindow* window = WindowForEvent(aEvent);
|
||||
if (!window || !WindowAcceptsEvent(window, aEvent))
|
||||
if (!window)
|
||||
return nil;
|
||||
|
||||
NSPoint windowEventLocation = nsCocoaUtils::EventLocationForWindow(aEvent, window);
|
||||
NSView* view = [[[window contentView] superview] hitTest:windowEventLocation];
|
||||
NS_ASSERTION(view, "How can the mouse be over a window but not over a view in that window?");
|
||||
return [view isKindOfClass:[ChildView class]] ? (ChildView*)view : nil;
|
||||
if (![view isKindOfClass:[ChildView class]])
|
||||
return nil;
|
||||
|
||||
ChildView* childView = (ChildView*)view;
|
||||
return WindowAcceptsEvent(window, aEvent, childView) ? childView : nil;
|
||||
}
|
||||
|
||||
static CGWindowLevel kDockWindowLevel = 0;
|
||||
@ -6469,7 +6518,8 @@ ChildViewMouseTracker::WindowForEvent(NSEvent* anEvent)
|
||||
}
|
||||
|
||||
BOOL
|
||||
ChildViewMouseTracker::WindowAcceptsEvent(NSWindow* aWindow, NSEvent* aEvent)
|
||||
ChildViewMouseTracker::WindowAcceptsEvent(NSWindow* aWindow, NSEvent* aEvent,
|
||||
ChildView* aView, BOOL aIsClickThrough)
|
||||
{
|
||||
// Right mouse down events may get through to all windows, even to a top level
|
||||
// window with an open sheet.
|
||||
@ -6495,7 +6545,7 @@ ChildViewMouseTracker::WindowAcceptsEvent(NSWindow* aWindow, NSEvent* aEvent)
|
||||
// accept mouse move events on context menus even when none of our windows
|
||||
// is active, which is the right thing to do.
|
||||
// For panels, the parent window is the XUL window that owns the panel.
|
||||
return WindowAcceptsEvent([aWindow parentWindow], aEvent);
|
||||
return WindowAcceptsEvent([aWindow parentWindow], aEvent, aView, aIsClickThrough);
|
||||
|
||||
case eWindowType_toplevel:
|
||||
case eWindowType_dialog:
|
||||
@ -6518,15 +6568,15 @@ ChildViewMouseTracker::WindowAcceptsEvent(NSWindow* aWindow, NSEvent* aEvent)
|
||||
}
|
||||
|
||||
if (!topLevelWindow ||
|
||||
[topLevelWindow isMainWindow] ||
|
||||
([topLevelWindow isMainWindow] && !aIsClickThrough) ||
|
||||
[aEvent type] == NSOtherMouseDown ||
|
||||
(([aEvent modifierFlags] & NSCommandKeyMask) != 0 &&
|
||||
[aEvent type] != NSMouseMoved))
|
||||
return YES;
|
||||
|
||||
// If we're here then we're dealing with a left click or mouse move on an
|
||||
// inactive window or something similar. Return NO for now.
|
||||
return NO;
|
||||
// inactive window or something similar. Ask Gecko what to do.
|
||||
return [aView inactiveWindowAcceptsMouseEvent:aEvent];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
@ -2392,9 +2392,9 @@ ContentPatternDrawCallback(void* aInfo, CGContextRef aContext)
|
||||
windowLocation = nsCocoaUtils::EventLocationForWindow(anEvent, self);
|
||||
target = [contentView hitTest:[contentView convertPoint:windowLocation fromView:nil]];
|
||||
// If the hit test failed, the event is targeted here but is not over the window.
|
||||
// Target it at the first responder.
|
||||
// Send it to our content view.
|
||||
if (!target)
|
||||
target = (NSView*)[self firstResponder];
|
||||
target = contentView;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -169,8 +169,13 @@
|
||||
function clearExpectedEvents() {
|
||||
while (gExpectedEvents.length > 0) {
|
||||
var expectedEvent = gExpectedEvents.shift();
|
||||
var errFun = expectedEvent.todoShouldHaveFired ? todo : ok;
|
||||
errFun(false, "didn't receive expected event: " + eventToString(expectedEvent));
|
||||
if (expectedEvent.sometimesFiresButShouldnt) {
|
||||
// We didn't really expect it anyway, so it's good that it didn't fire.
|
||||
ok(true, "Didn't receive unexpected event: " + eventToString(expectedEvent));
|
||||
} else {
|
||||
var errFun = expectedEvent.shouldFireButDoesnt || expectedEvent.shouldFireButSometimesDoesnt ? todo : ok;
|
||||
errFun(false, "Didn't receive expected event: " + eventToString(expectedEvent));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,21 +183,31 @@
|
||||
|
||||
function eventMonitor(e) {
|
||||
printDebug("got event: " + eventToString(e) + "\n");
|
||||
processEvent(e);
|
||||
}
|
||||
|
||||
function processEvent(e) {
|
||||
var expectedEvent = gExpectedEvents.shift();
|
||||
while (expectedEvent && expectedEvent.todoShouldHaveFired) {
|
||||
todo(false, "Should have got event: " + eventToString(expectedEvent));
|
||||
expectedEvent = gExpectedEvents.shift();
|
||||
}
|
||||
if (!expectedEvent) {
|
||||
ok(false, "received event I didn't expect: " + eventToString(e));
|
||||
return true;
|
||||
}
|
||||
if (e.type != expectedEvent.type) {
|
||||
// Didn't get expectedEvent.
|
||||
if (expectedEvent.sometimesFiresButShouldnt) {
|
||||
// We didn't really expect it anyway, so it's good that it didn't fire.
|
||||
ok(true, "Didn't receive unexpected event: " + eventToString(expectedEvent));
|
||||
} else {
|
||||
var errFun = expectedEvent.shouldFireButDoesnt || expectedEvent.shouldFireButSometimesDoesnt ? todo : ok;
|
||||
errFun(false, "Didn't receive expected event: " + eventToString(expectedEvent));
|
||||
}
|
||||
return processEvent(e);
|
||||
}
|
||||
gEventNum++;
|
||||
is(e.screenX, expectedEvent.screenX, gEventNum + " | wrong X coord for event " + eventToString(e));
|
||||
is(e.screenY, expectedEvent.screenY, gEventNum + " | wrong Y coord for event " + eventToString(e));
|
||||
is(e.type, expectedEvent.type, gEventNum + " | wrong event type for event " + eventToString(e));
|
||||
is(e.target, expectedEvent.target, gEventNum + " | wrong target for event " + eventToString(e));
|
||||
if (expectedEvent.todoShouldNotHaveFired) {
|
||||
if (expectedEvent.firesButShouldnt || expectedEvent.sometimesFiresButShouldnt) {
|
||||
todo(false, gEventNum + " | Got an event that should not have fired: " + eventToString(e));
|
||||
}
|
||||
}
|
||||
@ -234,6 +249,14 @@
|
||||
return _tooltip;
|
||||
})();
|
||||
var tests = [
|
||||
|
||||
// Part 1: Disallow click-through
|
||||
|
||||
function blockClickThrough(callback) {
|
||||
document.documentElement.setAttribute("clickthrough", "never");
|
||||
gRightWindow.document.documentElement.setAttribute("clickthrough", "never");
|
||||
callback();
|
||||
},
|
||||
// Enter the left window, which is focused.
|
||||
[150, 150, NSMouseMoved, null, left, [
|
||||
{ type: "mouseover", target: leftElem },
|
||||
@ -253,7 +276,7 @@
|
||||
{ type: "mousemove", target: leftElem },
|
||||
]],
|
||||
// Move over the right window, which is inactive.
|
||||
// Inactive windows shouldn't respond to mousemove events,
|
||||
// Inactive windows shouldn't respond to mousemove events when clickthrough="never",
|
||||
// so we should only get a mouseout event, no mouseover event.
|
||||
[400, 150, NSMouseMoved, null, right, [
|
||||
{ type: "mouseout", target: leftElem },
|
||||
@ -285,9 +308,7 @@
|
||||
[400, 150, NSLeftMouseDown, null, right, [
|
||||
{ type: "mousedown", target: rightElem },
|
||||
]],
|
||||
// Let's drag to the right without letting the button go. It would be better
|
||||
// if the mouseover event had fired as soon as the mouse entered the window,
|
||||
// and not only when dragging, but that's ok.
|
||||
// Let's drag to the right without letting the button go.
|
||||
[410, 150, NSLeftMouseDragged, null, right, [
|
||||
{ type: "mousemove", target: rightElem },
|
||||
]],
|
||||
@ -301,16 +322,16 @@
|
||||
// Ideally we'd be bracketing that event with over and out events, too, but it
|
||||
// probably doesn't matter too much.
|
||||
[150, 170, NSRightMouseDown, null, left, [
|
||||
{ type: "mouseover", target: leftElem, todoShouldHaveFired: true },
|
||||
{ type: "mouseover", target: leftElem, shouldFireButDoesnt: true },
|
||||
{ type: "mousedown", target: leftElem },
|
||||
{ type: "mouseout", target: leftElem, todoShouldHaveFired: true },
|
||||
{ type: "mouseout", target: leftElem, shouldFireButDoesnt: true },
|
||||
]],
|
||||
// Let go of the mouse.
|
||||
[150, 170, NSRightMouseUp, null, left, [
|
||||
{ type: "mouseover", target: leftElem, todoShouldHaveFired: true },
|
||||
{ type: "mouseover", target: leftElem, shouldFireButDoesnt: true },
|
||||
{ type: "mouseup", target: leftElem },
|
||||
{ type: "click", target: leftElem },
|
||||
{ type: "mouseout", target: leftElem, todoShouldHaveFired: true },
|
||||
{ type: "mouseout", target: leftElem, shouldFireButDoesnt: true },
|
||||
]],
|
||||
// Right clicking hasn't focused it, so the window is still inactive.
|
||||
// Let's focus it; this time without the mouse, for variaton's sake.
|
||||
@ -325,7 +346,6 @@
|
||||
[150, 170, NSMouseMoved, null, left, [
|
||||
{ type: "mousemove", target: leftElem },
|
||||
]],
|
||||
|
||||
// This was boring... let's introduce a popup. It will overlap both the left
|
||||
// and the right window.
|
||||
function openPopupInLeftWindow(callback) {
|
||||
@ -337,14 +357,14 @@
|
||||
[200, 80, NSMouseMoved, gPopup, left, [
|
||||
{ type: "mouseout", target: leftElem },
|
||||
{ type: "mouseover", target: gPopup },
|
||||
{ type: "mouseover", target: gPopup, todoShouldNotHaveFired: true },
|
||||
{ type: "mouseover", target: gPopup, firesButShouldnt: true },
|
||||
{ type: "mousemove", target: gPopup },
|
||||
{ type: "mousemove", target: gPopup, todoShouldNotHaveFired: true },
|
||||
{ type: "mousemove", target: gPopup, firesButShouldnt: true },
|
||||
]],
|
||||
// Move the mouse back over the left window outside the popup.
|
||||
[160, 170, NSMouseMoved, null, left, [
|
||||
{ type: "mouseout", target: gPopup },
|
||||
{ type: "mouseout", target: gPopup, todoShouldNotHaveFired: true },
|
||||
{ type: "mouseout", target: gPopup, firesButShouldnt: true },
|
||||
{ type: "mouseover", target: leftElem },
|
||||
{ type: "mousemove", target: leftElem },
|
||||
]],
|
||||
@ -352,15 +372,15 @@
|
||||
[190, 80, NSMouseMoved, gPopup, left, [
|
||||
{ type: "mouseout", target: leftElem },
|
||||
{ type: "mouseover", target: gPopup },
|
||||
{ type: "mouseover", target: gPopup, todoShouldNotHaveFired: true },
|
||||
{ type: "mouseover", target: gPopup, firesButShouldnt: true },
|
||||
{ type: "mousemove", target: gPopup },
|
||||
{ type: "mousemove", target: gPopup, todoShouldNotHaveFired: true },
|
||||
{ type: "mousemove", target: gPopup, firesButShouldnt: true },
|
||||
]],
|
||||
// ...and over into the right window. (... again)
|
||||
// It's inactive, so it shouldn't get mouseover events yet.
|
||||
[400, 170, NSMouseMoved, null, right, [
|
||||
{ type: "mouseout", target: gPopup },
|
||||
{ type: "mouseout", target: gPopup, todoShouldNotHaveFired: true },
|
||||
{ type: "mouseout", target: gPopup, firesButShouldnt: true },
|
||||
]],
|
||||
// Again, no mouse events please, even though a popup is open. (bug 425556)
|
||||
[400, 180, NSMouseMoved, null, right, [
|
||||
@ -372,7 +392,7 @@
|
||||
]],
|
||||
[400, 180, NSLeftMouseUp, null, right, [
|
||||
]],
|
||||
function verifyPopupClosed(callback) {
|
||||
function verifyPopupClosed2(callback) {
|
||||
is(gPopup.popupBoxObject.popupState, "closed", "popup should have closed when clicking");
|
||||
callback();
|
||||
},
|
||||
@ -398,18 +418,14 @@
|
||||
]],
|
||||
// Wait for the tooltip to appear.
|
||||
function (callback) {
|
||||
var timer = setTimeout(callback, 2000); // just in case the tooltip is shy
|
||||
eventListenOnce(rightElem, "popupshown", function () {
|
||||
clearTimeout(timer);
|
||||
callback();
|
||||
});
|
||||
eventListenOnce(rightElem, "popupshown", callback);
|
||||
},
|
||||
// Now the tooltip is visible.
|
||||
// Move the mouse a little to the right, but send the event to the tooltip's
|
||||
// widget, even though the mouse is not over the tooltip, because that's what
|
||||
// Mac OS X does.
|
||||
[411, 180, NSMouseMoved, tooltip, right, [
|
||||
{ type: "mousemove", target: rightElem, todoShouldHaveFired: !!navigator.oscpu.match(/Mac OS X 10\.6$/) },
|
||||
{ type: "mousemove", target: rightElem },
|
||||
]],
|
||||
// Move another pixel. This time send the event to the right widget.
|
||||
// However, that must not make a difference.
|
||||
@ -460,7 +476,6 @@
|
||||
[261, 171, NSLeftMouseDown, panel, left, [
|
||||
]],
|
||||
[261, 171, NSLeftMouseUp, panel, left, [
|
||||
{ type: "mouseup", target: panel },
|
||||
]],
|
||||
// This didn't focus the window, unfortunately, so let's do it ourselves.
|
||||
function raiseLeftWindowTakeTwo(callback) {
|
||||
@ -469,7 +484,287 @@
|
||||
// Now mouse events should get through to the panel (which is now over the
|
||||
// right window).
|
||||
[387, 170, NSMouseMoved, null, right, [
|
||||
{ type: "mouseover", target: panel },
|
||||
{ type: "mouseover", target: panel, shouldFireButSometimesDoesnt: true },
|
||||
{ type: "mousemove", target: panel, shouldFireButSometimesDoesnt: true },
|
||||
]],
|
||||
[387, 171, NSMouseMoved, null, left, [
|
||||
{ type: "mouseover", target: panel, sometimesFiresButShouldnt: true },
|
||||
{ type: "mousemove", target: panel },
|
||||
]],
|
||||
[388, 171, NSMouseMoved, panel, left, [
|
||||
{ type: "mousemove", target: panel },
|
||||
]],
|
||||
// Click the panel.
|
||||
[388, 171, NSLeftMouseDown, panel, left, [
|
||||
{ type: "mousedown", target: panel }
|
||||
]],
|
||||
[388, 171, NSLeftMouseUp, panel, left, [
|
||||
{ type: "mouseup", target: panel },
|
||||
{ type: "click", target: panel },
|
||||
]],
|
||||
|
||||
// Last test for this part: Hit testing in the Canyon of Nowhere -
|
||||
// the pixel row directly south of the panel, over the left window.
|
||||
// Before bug 515003 we wrongly thought the mouse wasn't over any window.
|
||||
[173, 200, NSMouseMoved, panel, left, [
|
||||
{ type: "mouseout", target: panel },
|
||||
{ type: "mouseover", target: leftElem },
|
||||
{ type: "mousemove", target: leftElem },
|
||||
]],
|
||||
[173, 201, NSMouseMoved, panel, left, [
|
||||
{ type: "mousemove", target: leftElem },
|
||||
]],
|
||||
|
||||
// Part 2: Allow click-through
|
||||
|
||||
function hideThatPanel(callback) {
|
||||
eventListenOnce(panel, "popuphidden", callback);
|
||||
panel.hidePopup();
|
||||
},
|
||||
function unblockClickThrough(callback) {
|
||||
document.documentElement.removeAttribute("clickthrough");
|
||||
gRightWindow.document.documentElement.removeAttribute("clickthrough");
|
||||
callback();
|
||||
},
|
||||
// Enter the left window, which is focused.
|
||||
[150, 150, NSMouseMoved, null, left, [
|
||||
{ type: "mousemove", target: leftElem }
|
||||
]],
|
||||
// Test that moving inside the window fires mousemove events.
|
||||
[170, 150, NSMouseMoved, null, left, [
|
||||
{ type: "mousemove", target: leftElem },
|
||||
]],
|
||||
// Leaving the window should fire a mouseout event...
|
||||
[170, 20, NSMouseMoved, null, left, [
|
||||
{ type: "mouseout", target: leftElem },
|
||||
]],
|
||||
// ... and entering a mouseover event.
|
||||
[170, 120, NSMouseMoved, null, left, [
|
||||
{ type: "mouseover", target: leftElem },
|
||||
{ type: "mousemove", target: leftElem },
|
||||
]],
|
||||
// Move over the right window, which is inactive but still accepts
|
||||
// mouse events.
|
||||
[400, 150, NSMouseMoved, null, right, [
|
||||
{ type: "mouseout", target: leftElem },
|
||||
{ type: "mouseover", target: rightElem },
|
||||
{ type: "mousemove", target: rightElem },
|
||||
]],
|
||||
// Left-clicking while holding Cmd and middle clicking should work
|
||||
// on inactive windows, but without making them active.
|
||||
[400, 150, NSLeftMouseDown, null, right, [
|
||||
{ type: "mousedown", target: rightElem },
|
||||
], NSCommandKeyMask],
|
||||
[400, 150, NSLeftMouseUp, null, right, [
|
||||
{ type: "mouseup", target: rightElem },
|
||||
{ type: "click", target: rightElem },
|
||||
], NSCommandKeyMask],
|
||||
[400, 150, NSOtherMouseDown, null, right, [
|
||||
{ type: "mousedown", target: rightElem },
|
||||
]],
|
||||
[400, 150, NSOtherMouseUp, null, right, [
|
||||
{ type: "mouseup", target: rightElem },
|
||||
{ type: "click", target: rightElem },
|
||||
]],
|
||||
// Clicking an inactive window should make it active
|
||||
[400, 150, NSLeftMouseDown, null, right, [
|
||||
{ type: "mousedown", target: rightElem },
|
||||
]],
|
||||
[400, 150, NSLeftMouseUp, null, right, [
|
||||
{ type: "mouseup", target: rightElem },
|
||||
{ type: "click", target: rightElem },
|
||||
]],
|
||||
// Now it's focused.
|
||||
[401, 150, NSLeftMouseDown, null, right, [
|
||||
{ type: "mousedown", target: rightElem },
|
||||
]],
|
||||
// Let's drag to the right without letting the button go.
|
||||
[410, 150, NSLeftMouseDragged, null, right, [
|
||||
{ type: "mousemove", target: rightElem },
|
||||
]],
|
||||
// Let go of the mouse.
|
||||
[410, 150, NSLeftMouseUp, null, right, [
|
||||
{ type: "mouseup", target: rightElem },
|
||||
{ type: "click", target: rightElem },
|
||||
]],
|
||||
// Now we're being sneaky. The left window is inactive, but *right*-clicks to it
|
||||
// should still get through. Test that.
|
||||
// Ideally we'd be bracketing that event with over and out events, too, but it
|
||||
// probably doesn't matter too much.
|
||||
[150, 170, NSRightMouseDown, null, left, [
|
||||
{ type: "mouseover", target: leftElem, shouldFireButDoesnt: true },
|
||||
{ type: "mousedown", target: leftElem },
|
||||
{ type: "mouseout", target: leftElem, shouldFireButDoesnt: true },
|
||||
]],
|
||||
// Let go of the mouse.
|
||||
[150, 170, NSRightMouseUp, null, left, [
|
||||
{ type: "mouseover", target: leftElem, shouldFireButDoesnt: true },
|
||||
{ type: "mouseup", target: leftElem },
|
||||
{ type: "click", target: leftElem },
|
||||
{ type: "mouseout", target: leftElem, shouldFireButDoesnt: true },
|
||||
]],
|
||||
// Right clicking hasn't focused it, so the window is still inactive.
|
||||
// Let's focus it; this time without the mouse, for variaton's sake.
|
||||
// Still, mouseout and mouseover events should fire.
|
||||
function raiseLeftWindow(callback) {
|
||||
clearExpectedEvents();
|
||||
gExpectedEvents.push({ screenX: 150, screenY: 170, type: "mouseout", target: rightElem });
|
||||
gExpectedEvents.push({ screenX: 150, screenY: 170, type: "mouseover", target: leftElem });
|
||||
focusAndThen(left, function () { SimpleTest.executeSoon(callback); });
|
||||
},
|
||||
// It's active, so it should respond to mousemove events now.
|
||||
[150, 170, NSMouseMoved, null, left, [
|
||||
{ type: "mousemove", target: leftElem },
|
||||
]],
|
||||
|
||||
// This was boring... let's introduce a popup. It will overlap both the left
|
||||
// and the right window.
|
||||
function openPopupInLeftWindow(callback) {
|
||||
eventListenOnce(gPopup, "popupshown", callback);
|
||||
gPopup.openPopupAtScreen(150, 50, true);
|
||||
},
|
||||
// Move the mouse over the popup.
|
||||
// We'll get duplicate events on the popup; ignore them.
|
||||
[200, 80, NSMouseMoved, gPopup, left, [
|
||||
{ type: "mouseout", target: leftElem },
|
||||
{ type: "mouseover", target: gPopup },
|
||||
{ type: "mouseover", target: gPopup, firesButShouldnt: true },
|
||||
{ type: "mousemove", target: gPopup },
|
||||
{ type: "mousemove", target: gPopup, firesButShouldnt: true },
|
||||
]],
|
||||
// Move the mouse back over the left window outside the popup.
|
||||
[160, 170, NSMouseMoved, null, left, [
|
||||
{ type: "mouseout", target: gPopup },
|
||||
{ type: "mouseout", target: gPopup, firesButShouldnt: true },
|
||||
{ type: "mouseover", target: leftElem },
|
||||
{ type: "mousemove", target: leftElem },
|
||||
]],
|
||||
// Back over the popup... (double events again)
|
||||
[190, 80, NSMouseMoved, gPopup, left, [
|
||||
{ type: "mouseout", target: leftElem },
|
||||
{ type: "mouseover", target: gPopup },
|
||||
{ type: "mouseover", target: gPopup, firesButShouldnt: true },
|
||||
{ type: "mousemove", target: gPopup },
|
||||
{ type: "mousemove", target: gPopup, firesButShouldnt: true },
|
||||
]],
|
||||
// ...and over into the right window. (... again)
|
||||
[400, 170, NSMouseMoved, null, right, [
|
||||
{ type: "mouseout", target: gPopup },
|
||||
{ type: "mouseout", target: gPopup, firesButShouldnt: true },
|
||||
{ type: "mouseover", target: rightElem },
|
||||
{ type: "mousemove", target: rightElem },
|
||||
]],
|
||||
[400, 180, NSMouseMoved, null, right, [
|
||||
{ type: "mousemove", target: rightElem },
|
||||
]],
|
||||
// Activate the right window with a click.
|
||||
[400, 180, NSLeftMouseDown, null, right, [
|
||||
{ type: "mousedown", target: rightElem },
|
||||
]],
|
||||
[400, 180, NSLeftMouseUp, null, right, [
|
||||
{ type: "mouseup", target: rightElem },
|
||||
{ type: "click", target: rightElem },
|
||||
]],
|
||||
function verifyPopupClosed2(callback) {
|
||||
is(gPopup.popupBoxObject.popupState, "closed", "popup should have closed when clicking");
|
||||
callback();
|
||||
},
|
||||
// Now the right window is active; click it again, just for fun.
|
||||
[400, 180, NSLeftMouseDown, null, right, [
|
||||
{ type: "mousedown", target: rightElem },
|
||||
]],
|
||||
[400, 180, NSLeftMouseUp, null, right, [
|
||||
{ type: "mouseup", target: rightElem },
|
||||
{ type: "click", target: rightElem },
|
||||
]],
|
||||
|
||||
// Time for our next trick: a tooltip!
|
||||
// Install the tooltip, but don't show it yet.
|
||||
function setTooltip(callback) {
|
||||
rightElem.setAttribute("tooltip", "tip");
|
||||
callback();
|
||||
},
|
||||
// Move the mouse to trigger the appearance of the tooltip.
|
||||
// ... and what's that, a mousemove event without preceding mouseover? Bad.
|
||||
[410, 180, NSMouseMoved, null, right, [
|
||||
{ type: "mousemove", target: rightElem },
|
||||
]],
|
||||
// Wait for the tooltip to appear.
|
||||
function (callback) {
|
||||
eventListenOnce(rightElem, "popupshown", callback);
|
||||
},
|
||||
// Now the tooltip is visible.
|
||||
// Move the mouse a little to the right, but send the event to the tooltip's
|
||||
// widget, even though the mouse is not over the tooltip, because that's what
|
||||
// Mac OS X does.
|
||||
[411, 180, NSMouseMoved, tooltip, right, [
|
||||
{ type: "mousemove", target: rightElem },
|
||||
]],
|
||||
// Move another pixel. This time send the event to the right widget.
|
||||
// However, that must not make a difference.
|
||||
[412, 180, NSMouseMoved, null, right, [
|
||||
{ type: "mousemove", target: rightElem },
|
||||
]],
|
||||
// Move up and click to make the tooltip go away.
|
||||
[412, 80, NSMouseMoved, null, right, [
|
||||
{ type: "mousemove", target: rightElem },
|
||||
]],
|
||||
[412, 80, NSLeftMouseDown, null, right, [
|
||||
{ type: "mousedown", target: rightElem },
|
||||
]],
|
||||
[412, 80, NSLeftMouseUp, null, right, [
|
||||
{ type: "mouseup", target: rightElem },
|
||||
{ type: "click", target: rightElem },
|
||||
]],
|
||||
// OK, next round. Open a panel in the left window, which is inactive.
|
||||
function openPanel2(callback) {
|
||||
eventListenOnce(panel, "popupshown", callback);
|
||||
panel.openPopupAtScreen(150, 150, false);
|
||||
},
|
||||
// The panel is parented, so it will be z-ordered over its parent but
|
||||
// under the active window.
|
||||
// Now we move the mouse over the part where the panel rect intersects the
|
||||
// right window's rect. Since the panel is under the window, all the events
|
||||
// should target the right window.
|
||||
// Try with sending to three different targets.
|
||||
[390, 170, NSMouseMoved, null, right, [
|
||||
{ type: "mousemove", target: rightElem },
|
||||
]],
|
||||
[390, 171, NSMouseMoved, null, left, [
|
||||
{ type: "mousemove", target: rightElem },
|
||||
]],
|
||||
[391, 171, NSMouseMoved, panel, left, [
|
||||
{ type: "mousemove", target: rightElem },
|
||||
]],
|
||||
// Now move off the right window, so that the mouse is directly over the
|
||||
// panel.
|
||||
[260, 170, NSMouseMoved, null, left, [
|
||||
{ type: "mouseout", target: rightElem },
|
||||
{ type: "mouseover", target: panel, shouldFireButSometimesDoesnt: true },
|
||||
{ type: "mousemove", target: panel, shouldFireButSometimesDoesnt: true },
|
||||
]],
|
||||
[260, 171, NSMouseMoved, null, left, [
|
||||
{ type: "mouseover", target: panel, sometimesFiresButShouldnt: true },
|
||||
{ type: "mousemove", target: panel, shouldFireButSometimesDoesnt: true },
|
||||
]],
|
||||
[261, 171, NSMouseMoved, panel, left, [
|
||||
{ type: "mouseover", target: panel, sometimesFiresButShouldnt: true },
|
||||
{ type: "mousemove", target: panel, shouldFireButSometimesDoesnt: true },
|
||||
]],
|
||||
// Let's be evil and click it.
|
||||
[261, 171, NSLeftMouseDown, panel, left, [
|
||||
{ type: "mousedown", target: panel },
|
||||
]],
|
||||
[261, 171, NSLeftMouseUp, panel, left, [
|
||||
{ type: "mouseup", target: panel },
|
||||
{ type: "click", target: panel },
|
||||
]],
|
||||
// This didn't focus the window, unfortunately, so let's do it ourselves.
|
||||
function raiseLeftWindowTakeTwo(callback) {
|
||||
focusAndThen(left, callback);
|
||||
},
|
||||
[387, 170, NSMouseMoved, null, right, [
|
||||
{ type: "mouseover", target: panel, sometimesFiresButShouldnt: true },
|
||||
{ type: "mousemove", target: panel },
|
||||
]],
|
||||
[387, 171, NSMouseMoved, null, left, [
|
||||
|
Loading…
Reference in New Issue
Block a user