Merge m-c to inbound.

This commit is contained in:
Ryan VanderMeulen 2013-01-03 17:01:32 -05:00
commit 743cecf4c4
23 changed files with 284 additions and 55 deletions

View File

@ -1,7 +1,7 @@
[ [
{ {
"size": 676536592, "size": 676733720,
"digest": "5aa3f1b523faa8996dbcde44a99d846740f80b5361d3109f36688c7bac86979861311c4e7d69b67d9ea1d7c56e20947a30576b3e3f08f7c1e42ec4c2192d92e1", "digest": "6ae117e64af1e8532004e9de44f172b5db88f42a91b8821503b3832de6e168f8c000229705a5110ce294065780a6371e7852dd76ddd8f3c6113892a093b6fc55",
"algorithm": "sha512", "algorithm": "sha512",
"filename": "gonk.tar.xz" "filename": "gonk.tar.xz"
} }

View File

@ -10,11 +10,11 @@
<default remote="linaro" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/> <default remote="linaro" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
<!-- Gonk specific things and forks --> <!-- Gonk specific things and forks -->
<project name="platform_build" path="build" remote="b2g" revision="273ba23d5c6c9f6a34995a3cc429804d1449ca9f"> <project name="platform_build" path="build" remote="b2g" revision="69380784721ae11af93ef4e1b5ce8a54e8570574">
<copyfile dest="Makefile" src="core/root.mk"/> <copyfile dest="Makefile" src="core/root.mk"/>
</project> </project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/> <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="7c43e273991a8a66afc88c888befb2830b7640e1"/> <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="ffc42185726384eaa80ea685bd9c95b7dab467c3"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="167b4c59a82b9130e385de786e8056d89a1cb8c3"/> <project name="rilproxy" path="rilproxy" remote="b2g" revision="167b4c59a82b9130e385de786e8056d89a1cb8c3"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="6ee1f8987ef36d688f97064c003ad57849dfadf2"/> <project name="moztt" path="external/moztt" remote="b2g" revision="6ee1f8987ef36d688f97064c003ad57849dfadf2"/>
@ -94,5 +94,6 @@
<!-- Information: platform/hardware/ti/omap4xxx is tagged with android-4.0.4_r2.1 --><project name="platform/hardware/ti/omap4xxx" path="hardware/ti/omap4xxx" revision="8be8e9a68c96b6cf43c08a58e7ecd7708737c599"/> <!-- Information: platform/hardware/ti/omap4xxx is tagged with android-4.0.4_r2.1 --><project name="platform/hardware/ti/omap4xxx" path="hardware/ti/omap4xxx" revision="8be8e9a68c96b6cf43c08a58e7ecd7708737c599"/>
<project name="platform/hardware/ti/wlan" path="hardware/ti/wlan" revision="60dfeb6e4448bfed707946ebca6612980f525e69"/> <project name="platform/hardware/ti/wlan" path="hardware/ti/wlan" revision="60dfeb6e4448bfed707946ebca6612980f525e69"/>
<project name="platform/hardware/ti/wpan" path="hardware/ti/wpan" revision="3ece7d9e08052989401e008bc397dbcd2557cfd0"/> <project name="platform/hardware/ti/wpan" path="hardware/ti/wpan" revision="3ece7d9e08052989401e008bc397dbcd2557cfd0"/>
<project name="Negatus" path="external/negatus" remote="mozilla" revision="7ed4efcee655f605455f9375a4e6c68cd078c459"/>
</manifest> </manifest>

View File

@ -432,7 +432,8 @@ nsContextMenu.prototype = {
setTarget: function (aNode, aRangeParent, aRangeOffset) { setTarget: function (aNode, aRangeParent, aRangeOffset) {
const xulNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; const xulNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
if (aNode.namespaceURI == xulNS || if (aNode.namespaceURI == xulNS ||
aNode.nodeType == Node.DOCUMENT_NODE) { aNode.nodeType == Node.DOCUMENT_NODE ||
this.isDisabledForEvents(aNode)) {
this.shouldDisplay = false; this.shouldDisplay = false;
return; return;
} }
@ -1290,6 +1291,16 @@ nsContextMenu.prototype = {
"contextMenu.hasBGImage = " + this.hasBGImage + "\n"; "contextMenu.hasBGImage = " + this.hasBGImage + "\n";
}, },
isDisabledForEvents: function(aNode) {
let ownerDoc = aNode.ownerDocument;
return
ownerDoc.defaultView &&
ownerDoc.defaultView
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils)
.isNodeDisabledForEvents(aNode);
},
isTargetATextBox: function(node) { isTargetATextBox: function(node) {
if (node instanceof HTMLInputElement) if (node instanceof HTMLInputElement)
return node.mozIsTextField(false); return node.mozIsTextField(false);

View File

@ -95,6 +95,9 @@ ContentAreaDropListener.prototype =
canDropLink: function(aEvent, aAllowSameDocument) canDropLink: function(aEvent, aAllowSameDocument)
{ {
if (this._eventTargetIsDisabled(aEvent))
return false;
let dataTransfer = aEvent.dataTransfer; let dataTransfer = aEvent.dataTransfer;
let types = dataTransfer.types; let types = dataTransfer.types;
if (!types.contains("application/x-moz-file") && if (!types.contains("application/x-moz-file") &&
@ -131,6 +134,8 @@ ContentAreaDropListener.prototype =
dropLink: function(aEvent, aName, aDisallowInherit) dropLink: function(aEvent, aName, aDisallowInherit)
{ {
aName.value = ""; aName.value = "";
if (this._eventTargetIsDisabled(aEvent))
return "";
let dataTransfer = aEvent.dataTransfer; let dataTransfer = aEvent.dataTransfer;
let [url, name] = this._getDropURL(dataTransfer); let [url, name] = this._getDropURL(dataTransfer);
@ -147,6 +152,18 @@ ContentAreaDropListener.prototype =
aName.value = name; aName.value = name;
return url; return url;
},
_eventTargetIsDisabled: function(aEvent)
{
let ownerDoc = aEvent.originalTarget.ownerDocument;
if (!ownerDoc || !ownerDoc.defaultView)
return false;
return ownerDoc.defaultView
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils)
.isNodeDisabledForEvents(aEvent.originalTarget);
} }
}; };

View File

@ -49,6 +49,8 @@ MOCHITEST_CHROME_FILES = \
test_csp_bug768029.html \ test_csp_bug768029.html \
test_bug800386.xul \ test_bug800386.xul \
test_csp_bug773891.html \ test_csp_bug773891.html \
test_bug816340.xul \
file_bug816340.xul \
test_domparsing.xul \ test_domparsing.xul \
test_bug814638.xul \ test_bug814638.xul \
host_bug814638.xul \ host_bug814638.xul \

View File

@ -0,0 +1,70 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=816340
-->
<window title="Mozilla Bug 816340"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="start();">
<label value="Mozilla Bug 816340"/>
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
function ok(val, msg) {
opener.wrappedJSObject.ok(val, msg);
}
var elems =
[
"input",
"textarea",
"select",
"fieldset",
"button",
];
var chromeDidGetEvent = false;
function chromeListener() {
chromeDidGetEvent = true;
}
function testElement(el, disabled, contentShouldGetEvent) {
chromeDidGetEvent = false;
var b = document.getElementById("browser");
b.contentDocument.body.innerHTML = null;
var e = b.contentDocument.createElement(el);
if (disabled) {
e.setAttribute("disabled", "true");
}
b.contentDocument.body.appendChild(e);
var contentDidGetEvent = false;
b.contentDocument.body.addEventListener("foo",
function() { contentDidGetEvent = true }, true);
b.addEventListener("foo", chromeListener, true);
e.dispatchEvent(new Event("foo"));
b.removeEventListener("foo", chromeListener, true);
ok(contentDidGetEvent == contentShouldGetEvent, "content: " + el + (disabled ? " disabled" : ""));
ok(chromeDidGetEvent, "chrome: " + el + (disabled ? " disabled" : ""));
}
function start() {
// Test common element.
testElement("div", false, true);
testElement("div", true, true);
for (var i = 0; i < elems.length; ++i) {
testElement(elems[i], false, true);
testElement(elems[i], true, false);
}
ok(true, "done");
opener.setTimeout("done()", 0);
window.close();
}
]]></script>
<browser id="browser" type="content" src="about:blank"/>
</window>

View File

@ -0,0 +1,31 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=816340
-->
<window title="Mozilla Bug 816340"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<!-- test results are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml">
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=816340"
target="_blank">Mozilla Bug 816340</a>
</body>
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
SimpleTest.waitForExplicitFinish();
function done() {
SimpleTest.finish();
}
addLoadEvent(function() {
window.open("file_bug816340.xul", "", "chrome");
});
]]></script>
</window>

View File

@ -100,15 +100,17 @@ public:
nsEventStatus aEventStatus, nsEventStatus aEventStatus,
bool aIsInAnon) bool aIsInAnon)
: nsEventChainVisitor(aPresContext, aEvent, aDOMEvent, aEventStatus), : nsEventChainVisitor(aPresContext, aEvent, aDOMEvent, aEventStatus),
mCanHandle(true), mForceContentDispatch(false), mCanHandle(true), mAutomaticChromeDispatch(true),
mRelatedTargetIsInAnon(false), mOriginalTargetIsInAnon(aIsInAnon), mForceContentDispatch(false), mRelatedTargetIsInAnon(false),
mWantsWillHandleEvent(false), mMayHaveListenerManager(true), mOriginalTargetIsInAnon(aIsInAnon), mWantsWillHandleEvent(false),
mParentTarget(nullptr), mEventTargetAtParent(nullptr) {} mMayHaveListenerManager(true), mParentTarget(nullptr),
mEventTargetAtParent(nullptr) {}
void Reset() { void Reset() {
mItemFlags = 0; mItemFlags = 0;
mItemData = nullptr; mItemData = nullptr;
mCanHandle = true; mCanHandle = true;
mAutomaticChromeDispatch = true;
mForceContentDispatch = false; mForceContentDispatch = false;
mWantsWillHandleEvent = false; mWantsWillHandleEvent = false;
mMayHaveListenerManager = true; mMayHaveListenerManager = true;
@ -124,6 +126,12 @@ public:
*/ */
bool mCanHandle; bool mCanHandle;
/**
* If mCanHandle is false and mAutomaticChromeDispatch is also false
* event will not be dispatched to the chrome event handler.
*/
bool mAutomaticChromeDispatch;
/** /**
* If mForceContentDispatch is set to true, * If mForceContentDispatch is set to true,
* content dispatching is not disabled for this event target. * content dispatching is not disabled for this event target.

View File

@ -197,7 +197,7 @@ public:
static void ResetMaxEtciCount() static void ResetMaxEtciCount()
{ {
NS_ASSERTION(!sCurrentEtciCount, "Wrong time to call ResetMaxEtciCount()!"); MOZ_ASSERT(!sCurrentEtciCount, "Wrong time to call ResetMaxEtciCount()!");
sMaxEtciCount = 0; sMaxEtciCount = 0;
} }
@ -438,6 +438,30 @@ int32_t ChainItemPool::sEtciPoolUsers = 0;
void NS_ShutdownChainItemPool() { ChainItemPool::Shutdown(); } void NS_ShutdownChainItemPool() { ChainItemPool::Shutdown(); }
nsEventTargetChainItem*
EventTargetChainItemForChromeTarget(ChainItemPool& aPool,
nsINode* aNode,
nsEventTargetChainItem* aChild = nullptr)
{
if (!aNode->IsInDoc()) {
return nullptr;
}
nsPIDOMWindow* win = aNode->OwnerDoc()->GetInnerWindow();
nsIDOMEventTarget* piTarget = win ? win->GetParentTarget() : nullptr;
NS_ENSURE_TRUE(piTarget, nullptr);
nsEventTargetChainItem* etci =
nsEventTargetChainItem::Create(aPool.GetPool(),
piTarget->GetTargetForEventTargetChain(),
aChild);
NS_ENSURE_TRUE(etci, nullptr);
if (!etci->IsValid()) {
nsEventTargetChainItem::Destroy(aPool.GetPool(), etci);
return nullptr;
}
return etci;
}
/* static */ nsresult /* static */ nsresult
nsEventDispatcher::Dispatch(nsISupports* aTarget, nsEventDispatcher::Dispatch(nsISupports* aTarget,
nsPresContext* aPresContext, nsPresContext* aPresContext,
@ -577,6 +601,13 @@ nsEventDispatcher::Dispatch(nsISupports* aTarget,
isInAnon); isInAnon);
targetEtci->PreHandleEvent(preVisitor); targetEtci->PreHandleEvent(preVisitor);
if (!preVisitor.mCanHandle && preVisitor.mAutomaticChromeDispatch && content) {
// Event target couldn't handle the event. Try to propagate to chrome.
nsEventTargetChainItem::Destroy(pool.GetPool(), targetEtci);
targetEtci = EventTargetChainItemForChromeTarget(pool, content);
NS_ENSURE_STATE(targetEtci);
targetEtci->PreHandleEvent(preVisitor);
}
if (preVisitor.mCanHandle) { if (preVisitor.mCanHandle) {
// At least the original target can handle the event. // At least the original target can handle the event.
// Setting the retarget to the |target| simplifies retargeting code. // Setting the retarget to the |target| simplifies retargeting code.
@ -584,6 +615,7 @@ nsEventDispatcher::Dispatch(nsISupports* aTarget,
targetEtci->SetNewTarget(t); targetEtci->SetNewTarget(t);
nsEventTargetChainItem* topEtci = targetEtci; nsEventTargetChainItem* topEtci = targetEtci;
while (preVisitor.mParentTarget) { while (preVisitor.mParentTarget) {
nsIDOMEventTarget* parentTarget = preVisitor.mParentTarget;
nsEventTargetChainItem* parentEtci = nsEventTargetChainItem* parentEtci =
nsEventTargetChainItem::Create(pool.GetPool(), preVisitor.mParentTarget, nsEventTargetChainItem::Create(pool.GetPool(), preVisitor.mParentTarget,
topEtci); topEtci);
@ -610,6 +642,24 @@ nsEventDispatcher::Dispatch(nsISupports* aTarget,
} else { } else {
nsEventTargetChainItem::Destroy(pool.GetPool(), parentEtci); nsEventTargetChainItem::Destroy(pool.GetPool(), parentEtci);
parentEtci = nullptr; parentEtci = nullptr;
if (preVisitor.mAutomaticChromeDispatch && content) {
// Even if the current target can't handle the event, try to
// propagate to chrome.
nsCOMPtr<nsINode> disabledTarget = do_QueryInterface(parentTarget);
if (disabledTarget) {
parentEtci = EventTargetChainItemForChromeTarget(pool,
disabledTarget,
topEtci);
if (parentEtci) {
parentEtci->PreHandleEvent(preVisitor);
if (preVisitor.mCanHandle) {
targetEtci->SetNewTarget(parentTarget);
topEtci = parentEtci;
continue;
}
}
}
}
break; break;
} }
} }

View File

@ -70,8 +70,8 @@ PR_STATIC_ASSERT((uint32_t)eButtonElementTypesMax < (uint32_t)NS_FORM_INPUT_ELEM
PR_STATIC_ASSERT((uint32_t)eInputElementTypesMax < 1<<8); PR_STATIC_ASSERT((uint32_t)eInputElementTypesMax < 1<<8);
#define NS_IFORMCONTROL_IID \ #define NS_IFORMCONTROL_IID \
{ 0xbc53dcf5, 0xbd4f, 0x4991, \ { 0x4b89980c, 0x4dcd, 0x428f, \
{ 0xa1, 0x87, 0xc4, 0x57, 0x98, 0x54, 0xda, 0x6e } } { 0xb7, 0xad, 0x43, 0x5b, 0x93, 0x29, 0x79, 0xec } }
/** /**
* Interface which all form controls (e.g. buttons, checkboxes, text, * Interface which all form controls (e.g. buttons, checkboxes, text,
@ -182,6 +182,10 @@ public:
*/ */
inline bool AllowDraggableChildren() const; inline bool AllowDraggableChildren() const;
virtual bool IsDisabledForEvents(uint32_t aMessage)
{
return false;
}
protected: protected:
/** /**

View File

@ -1188,7 +1188,7 @@ protected:
void* aData); void* aData);
// Returns true if the event should not be handled from PreHandleEvent // Returns true if the event should not be handled from PreHandleEvent
virtual bool IsElementDisabledForEvents(uint32_t aMessage, nsIFrame* aFrame); bool IsElementDisabledForEvents(uint32_t aMessage, nsIFrame* aFrame);
// The focusability state of this form control. eUnfocusable means that it // The focusability state of this form control. eUnfocusable means that it
// shouldn't be focused at all, eInactiveWindow means it's in an inactive // shouldn't be focused at all, eInactiveWindow means it's in an inactive

View File

@ -82,6 +82,7 @@ public:
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission); NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
NS_IMETHOD SaveState(); NS_IMETHOD SaveState();
bool RestoreState(nsPresState* aState); bool RestoreState(nsPresState* aState);
virtual bool IsDisabledForEvents(uint32_t aMessage);
nsEventStates IntrinsicState() const; nsEventStates IntrinsicState() const;
@ -251,17 +252,22 @@ nsHTMLButtonElement::ParseAttribute(int32_t aNamespaceID,
aResult); aResult);
} }
nsresult bool
nsHTMLButtonElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor) nsHTMLButtonElement::IsDisabledForEvents(uint32_t aMessage)
{ {
nsIFormControlFrame* formControlFrame = GetFormControlFrame(false); nsIFormControlFrame* formControlFrame = GetFormControlFrame(false);
nsIFrame* formFrame = NULL; nsIFrame* formFrame = NULL;
if (formControlFrame) { if (formControlFrame) {
formFrame = do_QueryFrame(formControlFrame); formFrame = do_QueryFrame(formControlFrame);
} }
return IsElementDisabledForEvents(aMessage, formFrame);
}
nsresult
nsHTMLButtonElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
{
aVisitor.mCanHandle = false; aVisitor.mCanHandle = false;
if (IsElementDisabledForEvents(aVisitor.mEvent->message, formFrame)) { if (IsDisabledForEvents(aVisitor.mEvent->message)) {
return NS_OK; return NS_OK;
} }

View File

@ -74,13 +74,19 @@ NS_IMPL_STRING_ATTR(nsHTMLFieldSetElement, Name, name)
// nsIConstraintValidation // nsIConstraintValidation
NS_IMPL_NSICONSTRAINTVALIDATION(nsHTMLFieldSetElement) NS_IMPL_NSICONSTRAINTVALIDATION(nsHTMLFieldSetElement)
bool
nsHTMLFieldSetElement::IsDisabledForEvents(uint32_t aMessage)
{
return IsElementDisabledForEvents(aMessage, nullptr);
}
// nsIContent // nsIContent
nsresult nsresult
nsHTMLFieldSetElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor) nsHTMLFieldSetElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
{ {
// Do not process any DOM events if the element is disabled. // Do not process any DOM events if the element is disabled.
aVisitor.mCanHandle = false; aVisitor.mCanHandle = false;
if (IsElementDisabledForEvents(aVisitor.mEvent->message, NULL)) { if (IsDisabledForEvents(aVisitor.mEvent->message)) {
return NS_OK; return NS_OK;
} }

View File

@ -51,6 +51,7 @@ public:
NS_IMETHOD_(uint32_t) GetType() const { return NS_FORM_FIELDSET; } NS_IMETHOD_(uint32_t) GetType() const { return NS_FORM_FIELDSET; }
NS_IMETHOD Reset(); NS_IMETHOD Reset();
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission); NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
virtual bool IsDisabledForEvents(uint32_t aMessage);
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
virtual nsXPCClassInfo* GetClassInfo(); virtual nsXPCClassInfo* GetClassInfo();
virtual nsIDOMNode* AsDOMNode() { return this; } virtual nsIDOMNode* AsDOMNode() { return this; }

View File

@ -2243,12 +2243,18 @@ nsHTMLInputElement::NeedToInitializeEditorForEvent(nsEventChainPreVisitor& aVisi
} }
} }
bool
nsHTMLInputElement::IsDisabledForEvents(uint32_t aMessage)
{
return IsElementDisabledForEvents(aMessage, GetPrimaryFrame());
}
nsresult nsresult
nsHTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor) nsHTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
{ {
// Do not process any DOM events if the element is disabled // Do not process any DOM events if the element is disabled
aVisitor.mCanHandle = false; aVisitor.mCanHandle = false;
if (IsElementDisabledForEvents(aVisitor.mEvent->message, GetPrimaryFrame())) { if (IsDisabledForEvents(aVisitor.mEvent->message)) {
return NS_OK; return NS_OK;
} }

View File

@ -104,6 +104,7 @@ public:
NS_IMETHOD SaveState(); NS_IMETHOD SaveState();
virtual bool RestoreState(nsPresState* aState); virtual bool RestoreState(nsPresState* aState);
virtual bool AllowDrop(); virtual bool AllowDrop();
virtual bool IsDisabledForEvents(uint32_t aMessage);
virtual void FieldSetDisabledChanged(bool aNotify); virtual void FieldSetDisabledChanged(bool aNotify);

View File

@ -1483,18 +1483,22 @@ nsHTMLSelectElement::GetAttributeMappingFunction() const
return &MapAttributesIntoRule; return &MapAttributesIntoRule;
} }
bool
nsresult nsHTMLSelectElement::IsDisabledForEvents(uint32_t aMessage)
nsHTMLSelectElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
{ {
nsIFormControlFrame* formControlFrame = GetFormControlFrame(false); nsIFormControlFrame* formControlFrame = GetFormControlFrame(false);
nsIFrame* formFrame = nullptr; nsIFrame* formFrame = nullptr;
if (formControlFrame) { if (formControlFrame) {
formFrame = do_QueryFrame(formControlFrame); formFrame = do_QueryFrame(formControlFrame);
} }
return IsElementDisabledForEvents(aMessage, formFrame);
}
nsresult
nsHTMLSelectElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
{
aVisitor.mCanHandle = false; aVisitor.mCanHandle = false;
if (IsElementDisabledForEvents(aVisitor.mEvent->message, formFrame)) { if (IsDisabledForEvents(aVisitor.mEvent->message)) {
return NS_OK; return NS_OK;
} }

View File

@ -271,6 +271,7 @@ public:
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission); NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
NS_IMETHOD SaveState(); NS_IMETHOD SaveState();
virtual bool RestoreState(nsPresState* aState); virtual bool RestoreState(nsPresState* aState);
virtual bool IsDisabledForEvents(uint32_t aMessage);
virtual void FieldSetDisabledChanged(bool aNotify); virtual void FieldSetDisabledChanged(bool aNotify);

View File

@ -97,6 +97,7 @@ public:
NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission); NS_IMETHOD SubmitNamesValues(nsFormSubmission* aFormSubmission);
NS_IMETHOD SaveState(); NS_IMETHOD SaveState();
virtual bool RestoreState(nsPresState* aState); virtual bool RestoreState(nsPresState* aState);
virtual bool IsDisabledForEvents(uint32_t aMessage);
virtual void FieldSetDisabledChanged(bool aNotify); virtual void FieldSetDisabledChanged(bool aNotify);
@ -665,17 +666,22 @@ nsHTMLTextAreaElement::GetAttributeMappingFunction() const
return &MapAttributesIntoRule; return &MapAttributesIntoRule;
} }
nsresult bool
nsHTMLTextAreaElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor) nsHTMLTextAreaElement::IsDisabledForEvents(uint32_t aMessage)
{ {
nsIFormControlFrame* formControlFrame = GetFormControlFrame(false); nsIFormControlFrame* formControlFrame = GetFormControlFrame(false);
nsIFrame* formFrame = NULL; nsIFrame* formFrame = NULL;
if (formControlFrame) { if (formControlFrame) {
formFrame = do_QueryFrame(formControlFrame); formFrame = do_QueryFrame(formControlFrame);
} }
return IsElementDisabledForEvents(aMessage, formFrame);
}
nsresult
nsHTMLTextAreaElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
{
aVisitor.mCanHandle = false; aVisitor.mCanHandle = false;
if (IsElementDisabledForEvents(aVisitor.mEvent->message, formFrame)) { if (IsDisabledForEvents(aVisitor.mEvent->message)) {
return NS_OK; return NS_OK;
} }

View File

@ -1126,6 +1126,7 @@ nsXULElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
// Stop building the event target chain for the original event. // Stop building the event target chain for the original event.
// We don't want it to propagate to any DOM nodes. // We don't want it to propagate to any DOM nodes.
aVisitor.mCanHandle = false; aVisitor.mCanHandle = false;
aVisitor.mAutomaticChromeDispatch = false;
// XXX sXBL/XBL2 issue! Owner or current document? // XXX sXBL/XBL2 issue! Owner or current document?
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(GetCurrentDoc())); nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(GetCurrentDoc()));

View File

@ -67,6 +67,7 @@
#include "nsIDOMFileHandle.h" #include "nsIDOMFileHandle.h"
#include "nsPrintfCString.h" #include "nsPrintfCString.h"
#include "nsViewportInfo.h" #include "nsViewportInfo.h"
#include "nsIFormControl.h"
using namespace mozilla; using namespace mozilla;
using namespace mozilla::dom; using namespace mozilla::dom;
@ -3090,3 +3091,26 @@ nsDOMWindowUtils::AllowScriptsToClose()
static_cast<nsGlobalWindow*>(window.get())->AllowScriptsToClose(); static_cast<nsGlobalWindow*>(window.get())->AllowScriptsToClose();
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsDOMWindowUtils::IsNodeDisabledForEvents(nsIDOMNode* aNode, bool* aRetVal)
{
*aRetVal = false;
if (!nsContentUtils::IsCallerChrome()) {
return NS_ERROR_DOM_SECURITY_ERR;
}
nsCOMPtr<nsINode> n = do_QueryInterface(aNode);
nsINode* node = n;
while (node) {
if (node->IsNodeOfType(nsINode::eHTML_FORM_CONTROL)) {
nsCOMPtr<nsIFormControl> fc = do_QueryInterface(node);
if (fc && fc->IsDisabledForEvents(NS_EVENT_NULL)) {
*aRetVal = true;
break;
}
}
node = node->GetParentNode();
}
return NS_OK;
}

View File

@ -40,7 +40,7 @@ interface nsIDOMTouch;
interface nsIDOMClientRect; interface nsIDOMClientRect;
interface nsIURI; interface nsIURI;
[scriptable, uuid(C98B7275-93C4-4EAD-B7CF-573D872C1071)] [scriptable, uuid(2196a216-ed3c-46dd-aa24-9f5b3ac17539)]
interface nsIDOMWindowUtils : nsISupports { interface nsIDOMWindowUtils : nsISupports {
/** /**
@ -1285,4 +1285,11 @@ interface nsIDOMWindowUtils : nsISupports {
* was created can be closed using scripts. * was created can be closed using scripts.
*/ */
void allowScriptsToClose(); void allowScriptsToClose();
/**
* In certain cases the event handling of nodes, form controls in practice,
* may be disabled. Such cases are for example the existence of disabled
* attribute or -moz-user-input: none/disabled.
*/
boolean isNodeDisabledForEvents(in nsIDOMNode aNode);
}; };

View File

@ -6563,34 +6563,6 @@ PresShell::HandleEventInternal(nsEvent* aEvent, nsEventStatus* aStatus)
} }
} }
if (eventTarget) { if (eventTarget) {
#ifdef MOZ_B2G
// Horrible hack for B2G to propagate events even from
// disabled form elements to chrome. See bug 804811.
// See also nsGenericHTMLFormElement::IsElementDisabledForEvents.
if (aEvent->message != NS_MOUSE_MOVE) {
nsINode* possibleFormElement = eventTarget->ChromeOnlyAccess() ?
static_cast<nsIContent*>(eventTarget.get())->
FindFirstNonChromeOnlyAccessContent() :
eventTarget;
if (possibleFormElement &&
possibleFormElement->IsNodeOfType(nsINode::eHTML_FORM_CONTROL)) {
nsEvent event(true, NS_EVENT_TYPE_NULL);
nsCOMArray<nsIDOMEventTarget> targets;
nsEventDispatcher::Dispatch(eventTarget, nullptr, &event, nullptr,
nullptr, nullptr, &targets);
nsCOMPtr<nsIContent> last;
if (targets.Count()) {
last = do_QueryInterface(targets[targets.Count() - 1]);
}
if (!targets.Count() ||
(last &&
nsContentUtils::ContentIsDescendantOf(last,
possibleFormElement))) {
aEvent->mFlags.mOnlyChromeDispatch = true;
}
}
}
#endif
if (aEvent->eventStructType == NS_COMPOSITION_EVENT || if (aEvent->eventStructType == NS_COMPOSITION_EVENT ||
aEvent->eventStructType == NS_TEXT_EVENT) { aEvent->eventStructType == NS_TEXT_EVENT) {
nsIMEStateManager::DispatchCompositionEvent(eventTarget, nsIMEStateManager::DispatchCompositionEvent(eventTarget,